This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
using namespace std;
//ifstream f ("sumzero.in");
//ofstream g ("sumzero.out");
constexpr int NMAX = 4e5 + 3;
constexpr int IDMAX = 2e5 + 3;
typedef long long LL;
int N;
vector <int> G[NMAX];
map <LL, int> mp;
int Root;
int Dad[NMAX];
int order[NMAX];
int ID[NMAX];
int poz[NMAX];
int First[IDMAX];
void Read () {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cin >> N;
for (int i = 1; i <= N; ++ i )
cin >> order[i];
}
void Precalculare () {
Root = N + 2;
G[N+2].push_back(N+1);
LL suff = 0;
mp[0] = N;
int val = N+1;
for (int i = N; i >= 1; -- i ) {
suff += 1LL * order[i];
int ind = mp[suff];
if (ind != 0) val = min(val, ind);
G[val+1].push_back(i);
Dad[i] = val+1;
mp[suff] = i-1;
}
}
void Dfs_Initial (int Node) {
ID[Node] = 1;
for (auto it : G[Node]) {
Dfs_Initial(it);
ID[Node] += ID[it];
}
}
int aux = 0;
int chains = 1;
void Split (int Node) {
int Max_Son = 0;
for (auto it : G[Node])
if (Max_Son == 0 || ID[Max_Son] < ID[it])
Max_Son = it;
ID[Node] = chains;
poz[Node] = ++ aux;
order[poz[Node]] = Node;
if (Max_Son == 0) return;
Split(Max_Son);
for (auto it : G[Node]) {
if (it == Max_Son) continue;
++ chains;
First[chains] = it;
Split(it);
}
}
void Do_HeavyPath () {
Dfs_Initial(Root);
First[1] = Root;
Split(Root);
for (int i = N+2; i >= 1; -- i )
G[i].clear();
}
int Query (int start, int Finish) {
int ans = 0;
while (start < Finish) {
if (First[ID[start]] <= Finish && Dad[First[ID[start]]] <= Finish) {
ans += poz[start] - poz[First[ID[start]]] + 1;
start = Dad[First[ID[start]]];
}
else {
int st = poz[First[ID[start]]];
int dr = poz[start];
int pos = poz[First[ID[start]]]-1;
while (st <= dr) {
int mij = (st + dr) / 2;
if (order[mij] > Finish) {
pos = mij;
st = mij + 1;
}
else dr = mij - 1;
}
++ pos;
ans += (poz[start] - pos);
break;
}
}
return ans;
}
int Q;
void Solve () {
cin >> Q;
for (; Q; -- Q ) {
int L, R;
cin >> L >> R;
cout << Query(L, R+1) << '\n';
}
}
int main () {
Read();
Precalculare();
Do_HeavyPath();
Solve();
return 0;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |