Submission #593272

#TimeUsernameProblemLanguageResultExecution timeMemory
593272VanillaDistributing Candies (IOI21_candies)C++17
100 / 100
1542 ms52724 KiB
#include <bits/stdc++.h> #include "candies.h" typedef long long int64; using namespace std; const int maxn = 2e5 + 5; vector <int> nw [maxn], old [maxn]; int64 aib [maxn]; int64 aib_query (int x) { int64 rs = 0; for (; x >= 0; x = (x & (x + 1)) - 1) { rs+=aib[x]; } return rs; } void aib_upd (int x, int64 d) { for (; x < maxn; x |= (x + 1)) { aib[x]+=d; } } struct node { int64 mx = -1e18; int64 mn = 1e18; int64 posmx = -1; int64 posmn = -1; int64 lazy = 0; void push (node &p1, node &p2, bool f) { if (!lazy) return; if (!f) p1.lazy+=lazy, p2.lazy+=lazy; mx+=lazy; mn+=lazy; lazy = 0; } node operator+ (const node &oth) { node now = {max(mx, oth.mx), min(mn, oth.mn), mx > oth.mx ? posmx: oth.posmx, mn < oth.mn ? posmn: oth.posmn}; return now; } }; node sgt[maxn * 8]; node build (int x, int l, int r) { if (l > r) return node(); if (l == r) return sgt[x] = {0, 0, l, l, 0}; int mid = (l + r) / 2; return sgt[x] = build(x * 2, l, mid) + build(x * 2 + 1, mid + 1, r); } node upd (int x, int l, int r, int il, int ir, int64 val) { sgt[x].push(sgt[x * 2], sgt[x * 2 + 1], l == r); if (r < il || l > ir) return sgt[x]; if (l >= il && r <= ir) { sgt[x].lazy+=val; sgt[x].push(sgt[x * 2], sgt[x * 2 + 1], l == r); return sgt[x]; } int mid = (l + r) / 2; return sgt[x] = upd(x * 2, l, mid, il, ir, val) + upd(x * 2 + 1, mid + 1, r, il, ir, val); } node query (int x, int l, int r, int il, int ir) { sgt[x].push(sgt[x * 2], sgt[x * 2 + 1], l == r); if (r < il || l > ir) return node(); if (l >= il && r <= ir) return sgt[x]; int mid = (l + r) / 2; return query(x * 2, l, mid, il, ir) + query(x * 2 + 1, mid + 1, r, il, ir); } vector<int> distribute_candies(vector<int> c, vector<int> l, vector<int> r, vector<int> v) { build(1, 0, maxn - 1); int n = c.size(); int m = v.size(); vector <int> rs (n); for (int i = 0; i < m; i++){ nw[l[i] + 1].push_back(i + 1); old[r[i] + 1].push_back(i + 1); } for (int i = 1; i <= n; i++){ for (int j: nw[i]) { upd(1, 0, maxn - 1, j, maxn - 1, v[j - 1]); aib_upd(j, v[j - 1]); } int l = 0, r = maxn - 1, f = -1; while (l <= r) { int mid = (l + r) / 2; node k = query(1, 0, maxn-1, mid, maxn - 1); if (k.mx - k.mn >= c[i - 1]) { f = mid; l = mid + 1; } else { r = mid - 1; } } int64 total = aib_query(maxn - 1); if (f == -1) rs[i - 1] = total - min(0ll, query(1, 0, maxn - 1, 0, maxn - 1).mn); else { int mn = query(1, 0, maxn - 1, f, maxn - 1).posmn; int mx = query(1, 0, maxn - 1, f, maxn - 1).posmx; assert(mn >= 0 && mx >= 0); if (mn > mx) rs[i - 1] = total - aib_query(mn); else rs[i - 1] = c[i - 1] + total - aib_query(mx); } for (int j: old[i]) { upd(1, 0, maxn - 1, j, maxn - 1, -v[j - 1]); aib_upd(j, -v[j - 1]); } } return rs; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...