voideachT(){ int n = read(), k = read(); vector<int> a(n), b(n); for (auto& it : a) it = read(); for (auto& it : b) it = read();
int l = 1, r = 1e9 + 1, m = -1; auto check = [&](int x) { int cnt = 0; for (int i = 0; i < n; ++i) { cnt += (a[i] < x) ? 0 : (a[i] - x) / b[i] + 1; if (cnt > k) return0; } return1; }; while (l < r) check(m = l + r >> 1) ? r = m : l = m + 1;
ll res = 0; int x = l; for (int i = 0; i < n; ++i) { ll num = (a[i] < x) ? 0 : (a[i] - x) / b[i] + 1; res += num * a[i] - 1ll * num * (num - 1) / 2 * b[i]; a[i] -= num * b[i]; k -= num; }
if (k > n) k = n; sort(a.begin(), a.end(), greater<>()); for (int i = 0; i < k; ++i) { if (a[i] > 0) res += a[i]; } printf("%lld\n", res); }
voideachT(){ int n = read(), m = read(), r = read(); // 牛 商店 邻居 for (int i = 1; i <= n; ++i) a[i] = read(); for (int i = 1; i <= m; ++i) b[i].a = read(), b[i].p = read(); for (int i = 1; i <= r; ++i) c[i] = read(); sort(a + 1, a + n + 1, greater<>()); sort(b + 1, b + m + 1); sort(c + 1, c + r + 1, greater<>()); for (int i = 1; i <= n; ++i) sa[i] = sa[i - 1] + a[i]; for (int i = 1; i <= m; ++i) sb[i] = sb[i - 1] + b[i].a; //前i个商店所需容量总和 for (int i = 1; i <= m; ++i) sbb[i] = sbb[i - 1] + b[i].a * b[i].p; //刚好满足前i个商店可获得的利润 for (int i = 1; i <= r; ++i) sc[i] = sc[i - 1] + c[i]; ll ans = 0; auto sell = [&](int t) { int p = lower_bound(sb + 1, sb + m + 1, sa[t]) - sb; return sbb[p - 1] + (sa[t] - sb[p - 1]) * b[p].p; }; auto rent = [&](int t) { return sc[t]; }; for (int i = max(0, n - m); i <= min(r, n); ++i) { ans = max(ans, sell(n - i) + rent(i)); } printf("%lld\n", ans); }
int n = read(); vector<int> a(n); for (int i = 0; i < n; ++i) a[i] = read(); auto dfs = [&](auto&& self, int l, int r, int done) -> int { if (l >= r) return0; int mid = l; for (int i = l; i < r; ++i) { if (a[i] < a[mid]) mid = i; } return (a[mid] - done) + self(self, l, mid, a[mid]) + self(self, mid + 1, r, a[mid]); }; printf("%d\n", dfs(dfs, 0, n, 0));
int n = read(); int now = 0, lst = 0, sum = 0; for (int i = 1; i <= n; ++i) { now = read(); sum += now > lst ? now - lst : 0; lst = now; } printf("%d\n", sum);
### [2023 CCPC 深圳 F. 一道好题](https://cpc.csgrandeur.cn/csgoj/problemset/problem?pid=1237)
vector<int> a(n); for (int i = 0; i < n; ++i) { cin >> a[i]; }
vector<pair<int, int>> res; auto dfs = [&](auto&& self, int l, int r) -> void { // 刚开始进循环时,所有值域范围为[l,r)的 a[i]值均为 l if (r - l < 2) return; int mid = l + r >> 1; for (int i = 0; i < n; ++i) { // 将目标值较大的a[i]凸出 if (mid <= a[i] && a[i] < r) { res.push_back({ 2, i + 1 }); } } for (int i = l + 1; i < mid; ++i) { // 将所有较大的a[i]变成mid res.push_back({ 1, i }); } self(self, l, mid); self(self, mid, r); }; dfs(dfs, 0, n + 1);
cout << res.size() << "\n"; for (auto& [a, b] : res) { cout << a << " " << b << "\n"; }
CDQ 分治
归并排序求逆序对
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
ll merge_sort(vector<int>& a){ auto solve = [&](auto&& self, int L, int R) -> ll { if (R - L <= 1) return0ll; int m = L + R >> 1; ll res = self(self, L, m) + self(self, m, R); vector<int> b; int l = L, r = m; while (l < m && r < R) { if (a[l] <= a[r]) b.push_back(a[l++]); else b.push_back(a[r++]), res += m - l; } while (l < m) b.push_back(a[l++]); while (r < R) b.push_back(a[r++]); copy(b.begin(), b.end(), a.begin() + L); return res; }; returnsolve(solve, 0, a.size()); }
迭代器版本也不错:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
using it = vector<int>::iterator; ll merge_sort(it L, it R){ if (distance(L, R) <= 1) return0; it m = L + (R - L) / 2; ll res = merge_sort(L, m) + merge_sort(m, R); vector<int> b; it l = L, r = m; while (l < m && r < R) { if (*l <= *r) b.push_back(*l++); else b.push_back(*r++), res += m - l; } while (l < m) b.push_back(*l++); while (r < R) b.push_back(*r++); copy(b.begin(), b.end(), L); return res; }
#include<bits/stdc++.h> usingnamespace std; constexprint N = 200010;
structnode { int x, y, z, ans, w; };
structBIT { int t[N]; voidupdate(int p, int x){ while (p < N) t[p] += x, p += p & -p; } intquery(int p){ int res = 0; while (p >= 1) res += t[p], p -= p & -p; return res; } intquery(int l, int r){ returnquery(r) - query(l - 1); } } t;