Submission #1297653

#TimeUsernameProblemLanguageResultExecution timeMemory
1297653aegSum Zero (RMI20_sumzero)C++20
100 / 100
172 ms19736 KiB
#include <bits/stdc++.h> using namespace std; int dfs(int s, vector<int> const&child, vector<int> const& start, vector<int>& heavy) { int sz = 1; int chmax = 0; for(int i = start[s]; i < start[s + 1]; i ++) { int ch = child[i]; int chsz = dfs(ch, child, start, heavy); sz += chsz; if(chsz > chmax) { heavy[s] = ch; chmax = chsz; } } return sz; } void decompose(int s, int h, vector<int> const&child,vector<int> const& start, 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, start, heavy, head, pos, curpos); for(int i = start[s]; i < start[s + 1]; i ++) { int ch = child[i]; if(ch != heavy[s]) { decompose(ch, ch, child, start, 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; unordered_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<int> child(n+ 1, 0); vector<int> start (n + 2, 0); vector<int> degree(n + 2, 0); for(int i = 0; i <= n; i ++) { if(next[i] < n && next[i] >= 0) degree[next[i] + 1]++; } start[0] = 0; for(int i = 0; i <=n + 1; i ++) start[i] = start[i - 1] + degree[i - 1]; vector<int> cur = start; for(int i = 0; i < n; i ++) if(next[i] < n && next[i] >= 0) child[cur[next[i] + 1]++] = i; cur.clear(); cur.shrink_to_fit(); 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, start, heavy); decompose(i, i, child, start, heavy, head, pos, cp); } } heavy.clear(); heavy.shrink_to_fit(); degree.clear(); degree.shrink_to_fit(); next.assign(n + 1, -1); for(int i = 0; i <= n; i ++) { for(int j = start[i]; j < start[i + 1]; j ++) { next[child[j]] = i - 1; } } start.clear(); start.shrink_to_fit(); 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...