Codeforces Round #833 (Div. 2) Cm
C. Zero-Sum Prefixes
考虑通过0来分块
我们令第一个块内没有0 其他都有
我们计算第一个块直接前缀和即可
后面因为每个块都有一个0 所以我们可以选择更改一次
我们更改显然是对他前缀和进行操作 我们直接处理出前缀和 再维护一下mx即可
我们思考一下为什么这样做是正确的
1.对于每一个0来说 不仅是要减去后面的前缀和 而且还要减去前面的总和
但是对于前面的总和来说我们顺手减了就是根本不用考虑
2.我们的前面的0取影响后面的0 显然不是最优的 因为我们再一个大区间内只用选一个数来减去肯定不如分开来可以任选两个数减去
code
void solve() {
int n;cin>>n;
vector<int>a(n+1),v[n+1];
for(int i=0;i<=n;i++)v[i].resize(1);
int cnt=0;
for(int i=1;i<=n;i++){
cin>>a[i];
if(!a[i]){
cnt++;
}
v[cnt].push_back(a[i]);
}
vector<int>s(v[0].size()+1);
int ans=0;
for(int i=1;i<v[0].size();i++){
s[i]=s[i-1]+v[0][i];
ans+=(s[i]==0);
}
for(int i=1;i<=n;i++){
if(v[i].size()==1)break;
s.resize(v[i].size()+1);
map<int,int>mp;
int mx=0;
for(int j=1;j<v[i].size();j++){
s[j]=s[j-1]+v[i][j];
mp[s[j]]++;
mx=max(mx,mp[s[j]]);
}
ans+=mx;
}
cout<<ans<<endl;
}