제출 #399835

#제출 시각아이디문제언어결과실행 시간메모리
399835anaykThe short shank; Redemption (BOI21_prison)C++14
80 / 100
2092 ms250712 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 bval[MAXN]; int par2[MAXN]; int nzero[MAXN]; int bit[MAXN]; int par[MAXN]; int min[MAXN], max[MAXN], tar[MAXN]; std::set<std::pair<int, int> > best; int root2(int x) { if(par2[x] < 0) return x; return par2[x] = root2(par2[x]); } 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]); } int merge2(int u, int v) { u = root2(u); v = root2(v); if(u == v) return u; if(par2[u] > par2[v]) u ^= v ^= u ^= v; par2[u] += par2[v]; nzero[u] = std::max(nzero[u], nzero[v]); par2[v] = u; return u; } struct seg { void bupd(int x, int v = 1) { x += 1; while(x < n+1) { bit[x] += v; x += x&(-x); } } int sum(int x) { x += 1; int ret = 0; while(x > 0) { ret += bit[x]; x -= x&(-x); } return ret; } void update(int x, int y) { while(true) { int it = nzero[root2(x)]; if(it > y) break; bupd(it); merge2(x, it+1); } } int query(int x, int y) { int ret = sum(y)-sum(x-1); return ret; } }; 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}); bval[x] = ch; } 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; for(int i = 0; i <= n; i++) { nzero[i] = i; par2[i] = -1; } 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) best.erase({bval[bef], bef}); best.erase({bval[af], af}); 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...