Submission #1297560

#TimeUsernameProblemLanguageResultExecution timeMemory
1297560aegSum Zero (RMI20_sumzero)C++20
0 / 100
3 ms568 KiB
#include <bits/stdc++.h>
using namespace std;

int dfs(int s, vector<vector<int>> const&child, vector<int>& dpth, vector<int>& heavy) {
	int sz = 1;
	int chmax = 0;
	for(auto &ch : child[s]) {
		dpth[ch] = dpth[s] + 1;
		int chsz = dfs(ch, child, dpth, heavy);
		sz += chsz;
		if(chsz > chmax) {
			heavy[s] = ch;
			chmax = chsz;
		}
	}
	return sz;
}

void decompose(int s, int h, vector<vector<int>> const&child, vector<int>const& heavy, vector<int>& head, vector<int>& pos, int& curpos) {
	head[s] = h, pos[s] = curpos++;
	if(heavy[s] != -1)
		decompose(heavy[s], h, child, heavy, head, pos, curpos);
	for(auto &ch:child[s]) if(ch != heavy[s]) {
		decompose(ch, ch, child, heavy, head, pos, curpos);
	}
}

signed main() {
	cin.tie(0)->sync_with_stdio(0);
	int n;
	cin >> n;
	vector<int> next(n + 1);
	next[n] = INT_MAX;
	{
		vector<int> a(n);
		vector<int> pref(n + 1);
		pref[0] = 0;

		map<int, int> mp;

		for(auto &x:a) cin >> x;
		for(int i = 0; i < n; i ++) pref[i + 1] = pref[i] + a[i];
		for(int i = n - 1; i >= 0; i --) {
			mp[pref[i + 1]] = i;
			if(mp.count(pref[i])) next[i] = min(mp[pref[i]], next[i + 1]);
			else next[i] = next[i + 1];
		}
	} // garbage collection
	vector<int> depth(n + 1, 0), head(n + 1, 0), pos(n + 1, -1);
	{
		vector<vector<int>> child(n + 1, vector<int>());
		vector<int> heavy(n + 1, -1);
		for(int i = 0; i < n; i ++) if(next[i] < n && next[i] >= 0) child[next[i] + 1].emplace_back(i);
		{
			int cp = 0;
			for(int i = n; i >= 0; i --) {
				if(pos[i] != -1) continue;
				dfs(i, child, depth, heavy);
				decompose(i, i, child, heavy, head, pos, cp);
			}
		}
	} // garbage collection
	
	vector<int> revpos(n + 1);
	for(int i = 0; i <= n; i ++) revpos[pos[i]] = i;

	for(int i = 0; i <= n; i ++) {
		if(next[i] == -1 || next[i] == INT_MAX) next[i] = -1;
		else next[i]++;
	}

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

		int curl = l;
		while(true) {
			if(head[curl] <= r) {
				if(next[head[curl]] < 0) {
					curl = head[curl];
					break;
				}
				else curl = next[head[curl]];
			}
			else break;
		}
		if(head[curl] == curl && next[curl] < 0) {
			cout << depth[l] - depth[curl] << '\n';
			continue;
		}
		int ll = pos[head[curl]], rr = pos[curl];
		int ans = rr;
		while(ll <= rr) {
			int m = (ll + rr) >> 1;
			if(revpos[m] <= r) {
				rr = m - 1;
				ans = min(ans, m);
			}
			else {
				ll = m + 1;
			}
		}
		cout << depth[l] - depth[revpos[ans]] << '\n';
	}
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...