Submission #1342550

#TimeUsernameProblemLanguageResultExecution timeMemory
1342550po_rag526Sum Zero (RMI20_sumzero)C++20
100 / 100
227 ms14152 KiB
#include <bits/stdc++.h>
using namespace std;

static const int MAXN = 400000 + 5;

int n, q;
long long pre[MAXN];
int par[MAXN], jumpPtr[MAXN], dep[MAXN];

int firstGreater(int u, int r) {
    while (u <= r) {
        if (jumpPtr[u] > r) u = par[u];
        else u = jumpPtr[u];
    }
    return u;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> n;
    for (int i = 1; i <= n; i++) {
        long long x;
        cin >> x;
        pre[i] = pre[i - 1] + x;
    }

    // Coordinate compression of prefix sums
    vector<long long> vals(pre, pre + n + 1);
    sort(vals.begin(), vals.end());
    vals.erase(unique(vals.begin(), vals.end()), vals.end());

    vector<int> last((int)vals.size(), -1);

    // Default parent = root (n+1)
    for (int i = 0; i <= n + 1; i++) par[i] = n + 1;

    // For each equal prefix sum, connect previous occurrence -> current occurrence
    for (int i = 0; i <= n; i++) {
        int id = lower_bound(vals.begin(), vals.end(), pre[i]) - vals.begin();
        if (last[id] != -1) par[last[id]] = i;
        last[id] = i;
    }

    // suffix minimum: earliest finishing zero-sum segment starting after i
    for (int i = n - 1; i >= 0; i--) {
        par[i] = min(par[i], par[i + 1]);
    }

    par[n] = n + 1;
    par[n + 1] = n + 1;

    // Build O(n)-memory jump structure from back to front
    dep[n + 1] = 0;
    jumpPtr[n + 1] = n + 1;

    for (int i = n; i >= 0; i--) {
        int p = par[i];
        dep[i] = dep[p] + 1;

        int jp = jumpPtr[p];
        if (dep[p] - dep[jp] == dep[jp] - dep[jumpPtr[jp]]) {
            jumpPtr[i] = jumpPtr[jp];
        } else {
            jumpPtr[i] = p;
        }
    }

    cin >> q;
    while (q--) {
        int l, r;
        cin >> l >> r;

        int u = l - 1;
        int x = firstGreater(u, r);
        cout << dep[u] - dep[x] - 1 << '\n';
    }

    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...