Submission #1349694

#TimeUsernameProblemLanguageResultExecution timeMemory
1349694samman_varshneySum Zero (RMI20_sumzero)C++20
0 / 100
2 ms1092 KiB
#include <iostream>
#include <vector>
#include <map>
#include <algorithm>

using namespace std;

const int MAXN = 400005;
const int LOG = 20;

int n, q;
long long c[MAXN];
long long p[MAXN];
int next_pos[MAXN];
int up[LOG][MAXN + 1];

void solve() {
    if (!(cin >> n)) return;
    for (int i = 1; i <= n; i++) {
        cin >> c[i];
        p[i] = p[i - 1] + c[i];
    }

    // Map to store the last seen index of a prefix sum
    map<long long, int> last_seen;
    last_seen[p[n]] = n + 1;

    // closest_zero[i] stores the end index of the earliest zero-sum 
    // subarray starting at or after index i.
    vector<int> closest_zero(n + 2, n + 2);
    
    // Process backwards to find the nearest zero-sum subarray
    for (int i = n; i >= 1; i--) {
        closest_zero[i] = closest_zero[i + 1];
        if (last_seen.count(p[i - 1])) {
            closest_zero[i] = min(closest_zero[i], last_seen[p[i - 1]]);
        }
        last_seen[p[i - 1]] = i;
    }

    // Binary Lifting Table Initialization
    // up[0][i] is where you land after completing one zero-sum subarray starting from i
    for (int i = 1; i <= n + 1; i++) {
        if (i <= n && closest_zero[i] <= n) {
            up[0][i] = closest_zero[i] + 1;
        } else {
            up[0][i] = n + 2; 
        }
    }
    up[0][n + 2] = n + 2;

    for (int k = 1; k < LOG; k++) {
        for (int i = 1; i <= n + 2; i++) {
            if (up[k - 1][i] <= n + 1) {
                up[k][i] = up[k - 1][up[k - 1][i]];
            } else {
                up[k][i] = n + 2;
            }
        }
    }

    cin >> q;
    while (q--) {
        int l, r;
        cin >> l >> r;
        int count = 0;
        int curr = l;

        // Binary lifting to find max jumps within [l, r]
        for (int k = LOG - 1; k >= 0; k--) {
            // If jumping 2^k zero-sum subarrays still ends within r
            if (up[k][curr] <= r + 1) {
                count += (1 << k);
                curr = up[k][curr];
            }
        }
        cout << count << "\n";
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    solve();
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...