제출 #1119298

#제출 시각아이디문제언어결과실행 시간메모리
1119298MateiKing80Sum Zero (RMI20_sumzero)C++14
61 / 100
233 ms24948 KiB
#include <bits/stdc++.h> using namespace std; int tata[1 << 19], ptr[1 << 19]; int a[1 << 19], ans[1 << 19]; int main() { ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n; cin >> n; for(int i = 1; i <= n; i ++) cin >> a[i], a[i] += a[i - 1]; unordered_map<int, int> mp; int last = n + 1; mp[a[n]] = n; ans[n + 2] = -1; ans[n + 1] = 0; tata[n + 1] = n + 2; tata[n + 2] = n + 2; for(int i = n; i; i --) { if(mp[a[i - 1]] != 0) last = min(last, mp[a[i - 1]]); mp[a[i - 1]] = i - 1; tata[i] = last + 1; ans[i] = 1 + ans[last + 1]; } int q; cin >> q; for(int i = n + 2; i; i --) { if(ans[ptr[ptr[tata[i]]]] - ans[ptr[tata[i]]] == ans[ptr[tata[i]]] - ans[tata[i]]) ptr[i] = ptr[ptr[tata[i]]]; else ptr[i] = tata[i]; } for(int i = 1; i <= q; i ++) { int l, r, li; cin >> l >> r; li = l; r ++; while(1) { if(ptr[l] <= r) l = ptr[l]; else if(tata[l] <= r) l = tata[l]; else break; } cout << ans[li] - ans[l] << '\n'; } } /* ne trebuie prima pereche de sume partiale egale care se afla la dreapta unui punct si facem binary lifting pe tot yessir NU AM MEMORIE CE E ASTA am o idee putem adauga incet incet lasturi de la dreapta la stanga putem sa facem binary lifting in O(1) memorie ca la arbori si adancimea va fi practic raspunsu? ca e cazul ala if(adanc[ptr[ptr[tata]]] - adanc[ptr[tata]] == adanc[ptr[tata]] - adanc[tata]) ptr[nod] = ptr[ptr[tata]]; si cam asta e tot sper */ /* 10 1 2 -3 0 1 -4 3 2 -1 1 3 1 10 1 5 2 9 */
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...