Codeforces Round #833 (Div. 2) C. Zero-Sum Prefixes
Let’s consider the prefix sum array s = [ a 1 , a 1 + a 2 , … , a 1 + a 2 + … + a n ] s=[a_1,a_1+a_2,\ldots,a_1+a_2+\ldots+a_n] s=[a1,a1+a2,…,a1+a2+…+an].
For every index i i i such that a i = 0 a_i=0 ai=0, if we change the value of a i a_i ai to x x x, then every element from the suffix [ s i , s i + 1 , … , s n ] [s_i,s_{i+1},\ldots,s_n] [si,si+1,…,sn] will be increased by x x x. Therefore, if a i 1 = a i 2 = … = a i k = 0 a_{i_1}=a_{i_2}=\ldots=a_{i_k}=0 ai1=ai2=…=aik=0, we’ll partition array s s s into multiple subarrays:
- [ s 1 , s 2 , … , s i 1 − 1 ] [s_1,s_2,\ldots,s_{i_1-1}] [s1,s2,…,si1−1];
-
[
s
i
2
,
s
i
2
+
1
,
…
,
s
i
3
−
1
]
[s_{i_2},s_{i_2+1},\ldots,s_{i_3-1}]
[si2,si2+1,…,si3−1];
… \ldots … -
[
s
i
k
,
s
i
k
+
1
,
…
,
s
n
]
[s_{i_k},s_{i_{k+1}},\ldots,s_n]
[sik,sik+1,…,sn];
Since none of the elements from the first subarray can be changed, it will contribute with the number of occurences of 0 0 0 in [ s 1 , s 2 , … , s i 1 − 1 ] [s_1,s_2,\ldots,s_{i_1-1}] [s1,s2,…,si1−1] towards the final answer.
For each of the other subarrays [ s l , s l + 1 , … , s r ] [s_l,s_{l+1},\ldots,s_r] [sl,sl+1,…,sr], let x x x be the most frequent element in the subarray, appearing f r [ x ] fr[x] fr[x] times. Since a l = 0 a_l=0 al=0, we can change the value of a l a_l al to − x -x −x. In this case, every x x x in this subarray will become equal to 0 0 0, and our current subarray will contribute with f r [ x ] fr[x] fr[x] towards the final answer.
Time complexity per testcase: O ( N l o g N ) O(NlogN) O(NlogN)
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int main()
{
int T;cin>>T;
while(T--)
{
int n;cin>>n;
map<LL,LL> b;
bool ok_zero=false;
LL sum=0,mx=0,res=0;
for(int i=0;i<n;i++)
{
int x;cin>>x;
if(x==0)
{
if(ok_zero) res+=mx;
else res+=b[0];
ok_zero=true;
mx=0;
b.clear();
}
sum+=x;
b[sum]++;
mx=max(mx,b[sum]);
}
if(ok_zero) res+=mx;
else res+=b[0];
cout<<res<<endl;
}
return 0;
}