AtCoder Grand Contest 023 A - Zero-Sum Ranges

Time limit : 2sec / Memory limit : 256MB

Score : 200 points

Problem Statement

We have an integer sequence A, whose length is N.

Find the number of the non-empty contiguous subsequences of A whose sums are 0. Note that we are counting the ways to take out subsequences. That is, even if the contents of some two subsequences are the same, they are counted individually if they are taken from different positions.

Constraints

  • 1≤N≤2×105
  • −109≤Ai≤109

All values in input are integers.

 

https://agc023.contest.atcoder.jp/tasks/agc023_a

题意:给一个数组求出数组中连续字串合为0的个数

Solution

n的平方算法会超时,一开始想着dp可是空间也不够;

首先看样例

6
1 3 -4 2 2 -2
我们计算前面的合为
1 4 0 2 4 2
我们可以发现相同的两个数之间之间经过的数的合一定是0;
例如第一个4 和第二个4 之间是 -4 + 2 +2=0所以我们发现规律只要找到相同的数的个数让他们之间两两连接就是个数
如果合为0代表从第一个开始到他的合就是0所以要额外加上0的个数
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=250000+50;
ll  num[maxn];
ll sum[maxn];
ll he(ll n){
        if(n==1)
                return 0;
        if(n==0)
                return 0;
        return (n*(n-1))/2;
}
map<ll,int>mp;
int main()
{
    //std::ios::sync_with_stdio(false);
    int n;
    scanf("%d",&n);
    long long summ=0;
    memset(sum,0,sizeof(sum));
    for(int i=1;i<=n;i++){
        scanf("%lld",&num[i]);
        sum[i]=sum[i-1]+num[i];
    }
    for(int i=1;i<=n;i++){
        if(mp[sum[i]]==0)mp[sum[i]]++;
        else{
                mp[sum[i]]++;
        }

    }
    map<ll,int>::iterator it;
    for(it=mp.begin();it!=mp.end();it++){
        //cout<<it->first<<" "<<it->second<<endl;
        if(it->first==0)
        summ+=(he(it->second)+(it->second));
        else if(it->second>1){
                if(it->first!=0)
                        summ+=he(it->second);

        }

    }
    printf("%lld\n",summ);
    return 0;
}

 

转载于:https://www.cnblogs.com/luowentao/p/8970061.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值