Submission #473938

#TimeUsernameProblemLanguageResultExecution timeMemory
473938model_codeTortoise (CEOI21_tortoise)C++17
100 / 100
1096 ms46924 KiB
#include <bits/stdc++.h> using namespace std; #define _ << " " << const int MAXN = 5e5 + 5; const int off = 1 << 19; const int inf = 1e9; int a[MAXN]; int l[MAXN]; int r[MAXN]; int before[MAXN]; unordered_map<int, int> specialChair; typedef pair<int, int> pii; struct Tournament { vector<int> t; vector<int> p; Tournament() { t.resize(2 * off); p.resize(2 * off); } void init() { for (int i = off; i < 2 * off; ++i) { t[i] = inf + (i - off); } for (int i = off - 1; i; i--) { t[i] = min(t[i * 2], t[i * 2 + 1]); } } void prop(int x) { if (p[x]) { t[x] += p[x]; if (x < off) { p[x * 2] += p[x]; p[x * 2 + 1] += p[x]; } p[x] = 0; } } void upd(int a, int b, int v, int x = 1, int lo = 0, int hi = off) { if (lo >= a && hi <= b) { p[x] += v; prop(x); return; } prop(x); if (lo >= b || hi <= a) return; int mi = (lo + hi) >> 1; upd(a, b, v, x * 2, lo, mi); upd(a, b, v, x * 2 + 1, mi, hi); t[x] = min(t[x * 2], t[x * 2 + 1]); } int get(int a, int b, int x = 1, int lo = 0, int hi = off) { if (lo >= b || hi <= a) return inf; prop(x); if (lo >= a && hi <= b) { return t[x]; } int mi = (lo + hi) >> 1; return min(get(a, b, x * 2, lo, mi), get(a, b, x * 2 + 1, mi, hi)); } } special, updates, tracker; void moveSpecial(int a, int b) { special.upd(a, a+1, +inf); special.upd(b, b+1, -inf); } void addSpecial(int a) { special.upd(a, a+1, -inf); } long long sum; void solve(int x, int d, int type) { int cnt = 0; while(a[x] > 0) { // check if this is valid with previous chairs if (tracker.get(x, off) < 2 * d) { break; } // check if this chair can be taken if (x - updates.get(x, x + 1) < type * d * 2) { break; } // if this is segment with right storage if (r[x] != -1) { int spec = specialChair[r[x]]; if (type) spec = min(spec, x); if (a[spec] == 1 && spec == x) { if (!type) break; spec = before[spec]; } if (spec <= l[x]) break; if (a[spec] <= 0) break; moveSpecial(specialChair[r[x]], spec); special.upd(x + type, off, -2 * d); int diff = special.get(0, off); if (diff < 0) { special.upd(x + type, off, 2 * d); moveSpecial(spec, specialChair[r[x]]); break; } specialChair[r[x]] = spec; } if (cnt == 0) { tracker.upd(x, x + 1, - inf - 2 * d * (type - 1)); } tracker.upd(x, off, -2 * d); updates.upd(x, off, 2 * d); a[x] --; sum --; cnt ++; } } int main() { int n; cin >> n; for (int i = 0; i < n; ++i) { cin >> a[i]; if (a[i] != -1) sum += a[i]; } int tmp = -1; for (int i = 0; i < n; ++i) { if (a[i] == -1) { tmp = i; } l[i] = tmp; } tmp = -1; for (int i = n - 1; i >= 0; --i) { if (a[i] == -1) { tmp = i; } r[i] = tmp; } tmp = -1; for (int i = 0; i < n; ++i) { before[i] = tmp; if (a[i] > 0) { tmp = i; } } special.init(); tracker.init(); // setup sepcial chair moves (left on first pass) for (int i = 0; i < n; ++i) { if (a[i] > 0 && r[i] != -1 && before[r[i]] == i) { addSpecial(i); specialChair[r[i]] = i; } } vector<pair<int, pii>> candidates; for (int i = 0; i < n; ++i) { if (a[i] > 0) { if (r[i] != -1) { candidates.push_back({r[i] - i, {i, 1}}); } if (l[i] != -1) { candidates.push_back({i - l[i], {i, 0}}); } } } sort(candidates.begin(), candidates.end()); for (auto candidate : candidates) { int x = candidate.second.first; int d = candidate.first; int type = candidate.second.second; solve(x, d, type); } for (int i = 0; i < n; ++i) { if (a[i] > 0 && r[i] != -1) { a[r[i]] = -2; } if (a[i] == -2) sum --; } cout << sum << endl; }
#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...