Submission #399807

#TimeUsernameProblemLanguageResultExecution timeMemory
399807anaykThe short shank; Redemption (BOI21_prison)C++14
80 / 100
2045 ms68076 KiB
#include <iostream> #include <vector> #include <set> #define int long long #define left (id+1) #define mid ((l+r)/2) #define right (id+2*(mid-l+1)) const int MAXN = 2000006; int n, d, t; int par[MAXN]; int min[MAXN], max[MAXN], tar[MAXN]; std::set<std::pair<int, int> > best; int root(int x) { if(par[x] < 0) return x; return par[x] = root(par[x]); } void merge(int u, int v) { u = root(u); v = root(v); if(u == v) return; if(par[u] > par[v]) u ^= v ^= u ^= v; par[u] += par[v]; par[v] = u; tar[u] = std::max(tar[u], tar[v]); max[u] = std::max(max[u], max[v]); min[u] = std::min(min[u], min[v]); } struct seg { std::vector<int> arr, lazy; void push(int id, int l, int r) { if(lazy[id]) { lazy[id] = 0; lazy[left] = lazy[right] = 1; arr[left] = mid-l+1; arr[right] = r-mid; } } void update(int x, int y, int id = 0, int l = 0, int r = n-1) { if(y < l || r < x) return; if(x <= l && r <= y) { arr[id] = r-l+1; lazy[id] = 1; return; } push(id, l, r); update(x, y, left, l, mid); update(x, y, right, mid+1, r); arr[id] = arr[left] + arr[right]; } int query(int x, int y, int id = 0, int l = 0, int r = n-1) { if(y < l || r < x) return 0; if(x <= l && r <= y) { return arr[id]; } push(id, l, r); return query(x, y, left, l, mid) + query(x, y, right, mid+1, r); } }; seg tree; int getL(int x) { if(min[x] == 0) return -1; return root(min[x]-1); } int getR(int x) { if(max[x] == n-1) return -1; return root(max[x]+1); } void tog(int x, int y) { int nex = getR(x); if(nex == -1) return; int r = std::min(tar[x], max[nex]); int l = min[nex]; int ch = r-l+1-tree.query(l, r); if(y == 1) best.insert({ch, x}); else { best.erase({ch, x}); if(y == 0) tree.update(l, r); } } signed main() { std::ios::sync_with_stdio(false); std::cin.tie(0); std::cin >> n >> d >> t; tree.arr = tree.lazy = std::vector<int>(2*n-1, 0); for(int i = 0; i < n; i++) { int val; std::cin >> val; par[i] = -1; min[i] = max[i] = i; tar[i] = i+t-val; if(tar[i] >= i) tree.update(i, i); } for(int i = 0; i+1 < n; i++) tog(i, 1); while(d < n-1) { int cur = (*best.begin()).second; int bef = getL(cur); int af = getR(cur); if(bef != -1) tog(bef, -1); tog(af, -1); tog(cur, 0); merge(cur, af); cur = root(cur); if(getR(cur) != -1) tog(cur, 1); if(bef != -1) tog(bef, 1); d++; } std::cout << tree.query(0, n-1) << std::endl; return 0; }
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...