Codeforces Round #833 (Div. 2) C. Zero-Sum Prefixes

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,,si11];
  • [ 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,,si31];
    … \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,,si11] 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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wa_Automata

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值