Submission #544712

#TimeUsernameProblemLanguageResultExecution timeMemory
544712eecsTortoise (CEOI21_tortoise)C++17
100 / 100
726 ms48456 KiB
#include <bits/stdc++.h>
using namespace std;

typedef pair<int, int> pii;
const int maxn = 500010, offset = 1 << 19, INF = 1e9;
int n, a[maxn], l[maxn], r[maxn], before[maxn];
unordered_map<int, int> specialChair;

struct SEG {
    vector<int> t, p;
    SEG() { t.resize(2 * offset), p.resize(2 * offset); }

    void init() {
        for (int i = offset; i < 2 * offset; i++) {
            t[i] = INF + (i - offset);
        }
        for (int i = offset - 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 < offset) {
                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 = offset) {
        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 = offset) {
        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) {
        if (tracker.get(x, offset) < 2 * d) break;
        if (x - updates.get(x, x + 1) < type * d * 2) break;
        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, offset, -2 * d);
            int diff = special.get(0, offset);
            if (diff < 0) {
                special.upd(x + type, offset, 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, offset, -2 * d);
        updates.upd(x, offset, 2 * d);
        a[x]--, sum--, cnt++;
    }
}

int main() {
    ios::sync_with_stdio(0), cin.tie(0);
    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();
    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>> cand;
    for (int i = 0; i < n; i++) if (a[i] > 0) {
        if (r[i] != -1) cand.push_back({r[i] - i, {i, 1}});
        if (l[i] != -1) cand.push_back({i - l[i], {i, 0}});
    }
    sort(cand.begin(), cand.end());
    for (auto &p : cand) {
        solve(p.second.first, p.first, p.second.second);
    }
    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 << "\n";
    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...