Submission #1297615

#TimeUsernameProblemLanguageResultExecution timeMemory
1297615aegSum Zero (RMI20_sumzero)C++20
61 / 100
241 ms30632 KiB
#include <bits/stdc++.h>
using namespace std;

struct linked {
	struct node{
		int val;
		node* nxt;
		node(int val):val(val), nxt(nullptr){}
	};
	node* head = nullptr,* tail = nullptr;
	~linked() {
		node* cur = head;
		while(cur != nullptr) {
			node* nxt = cur->nxt;
			delete cur;
			cur = nxt;
		}
		head = nullptr;
		tail = nullptr;
	}

	void push_back(int val) {
		node* nw = new node(val);
		if(head == nullptr) {
			tail = head = nw;
		}
		else {
			tail->nxt = nw;
			tail = nw;
		}
	}
	struct Iterator {
		node* crr;
		Iterator(node* crr):crr(crr) {}
		int& operator* () const {
			if(!crr) throw out_of_range("");
			return crr->val;
		}
		Iterator & operator++() {
			if(crr) crr = crr->nxt;
			return *this;
		}

		bool operator!=(const Iterator& rhs) const {
			return crr != rhs.crr;
		}
	};
	Iterator begin() const { return Iterator(head);}
	Iterator end() const { return Iterator(nullptr);}
};


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

void decompose(int s, int h, vector<linked> 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];
		}

		pref.clear();
		pref.shrink_to_fit();
		a.clear();
		a.shrink_to_fit();
		mp.clear();
	} // garbage collection
	vector<int> head(n + 1, 0), pos(n + 1, -1);
	{
		vector<linked> child(n + 1);
		for(int i = 0; i < n; i ++) if(next[i] < n && next[i] >= 0) child[next[i] + 1].push_back(i);
		next.clear();
		next.shrink_to_fit();
		vector<int> heavy(n + 1, -1);
		{
			int cp = 0;
			for(int i = n; i >= 0; i --) {
				if(pos[i] != -1) continue;
				dfs(i, child, heavy);
				decompose(i, i, child, heavy, head, pos, cp);
			}
		}
		heavy.clear();
		heavy.shrink_to_fit();
		next.assign(n + 1, -1);
		for(int i = 0; i < n; i ++) for(auto &x:child[i]) next[x] = i - 1;
		child.clear();
		child.shrink_to_fit();
	} // 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;
		int curd = 0;
		while(true) {
			if(head[curl] <= r) {
				if(next[head[curl]] < 0) {
					curd += pos[curl] - pos[head[curl]];
					curl = head[curl];
					break;
				}
				else {
					curd += pos[curl] - pos[head[curl]]+ 1;
					curl = next[head[curl]];
				}
			}
			else break;
		}
		if(head[curl] == curl && next[curl] < 0) {
			if(curl > r) cout << "0\n";
			else cout << curd << '\n';
			continue;
		}
		int ll = pos[head[curl]], rr = pos[curl];
		int ans = INT_MAX;
		while(ll <= rr) {
			int m = (ll + rr) >> 1;
			if(revpos[m] <= r) {
				rr = m - 1;
				ans = min(ans, m);
			}
			else {
				ll = m + 1;
			}
		}
		if(ans == INT_MAX) cout  << max(0, curd - 1) << '\n';
		else cout << curd + pos[curl] - ans << '\n';
	}
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...