codeforces-1333C-Eugene and an array

传送门:https://codeforces.com/contest/1333/problem/C

题意:如果一个数组的子数组(连续)里的值相加都不为0,那么称他为好数组,给出一个数组,问他的多少子数组是好数组(包括它本身)

一个好数组就不含总价值为0的子数组,那么如何判断他含不含总价值为0的子数组呢?

一个前缀和就搞得定,两个前缀和相等的数中间夹着的就是总价值为0的子数组,对吧

那么问题就变成了:对于每个以R为右端点的子数组,如何找到最小的左端点L,满足前缀和区间[L,R]的数字都不相同

然后双指针维护

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int a[200009],b[200009],z[200009];
ll sum[200009];
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]),sum[i]=sum[i-1]+a[i];
    map<ll,int>mp;
    ll ans=0;
    int l=0;
    mp[0]=1;
    for(int i=1;i<=n;i++)
    {
        while(mp[sum[i]]) mp[sum[l++]]--;
        mp[sum[i]]++;
        ans+=(i-l);
    }
    printf("%lld\n",ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/YangKun-/p/12683913.html
今日推荐