Submission #399823

#TimeUsernameProblemLanguageResultExecution timeMemory
399823anaykThe short shank; Redemption (BOI21_prison)C++14
70 / 100
2032 ms71480 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 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::set<int> arr; std::vector<int> bit; void bupd(int x, int v = 1) { x += 1; while(x < bit.size()) { 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) { auto it = arr.lower_bound(x); if(it == arr.end() || (*it) > y) break; bupd(*it); arr.erase(it); } } 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; tree.bit = std::vector<int>(n+1, 0); for(int i = 0; i < n; i++) tree.arr.insert(i); 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; }

Compilation message (stderr)

prison.cpp: In member function 'void seg::bupd(long long int, long long int)':
prison.cpp:50:13: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   50 |     while(x < bit.size()) {
      |           ~~^~~~~~~~~~~~
#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...