zoukankan      html  css  js  c++  java
  • 1333C.Engene and an array(前缀和)

    Eugene喜欢使用数组。今天,他需要你的帮助来完成一项具有挑战性的任务。

    数组c是数组b的子数组,如果c可以从b中通过从开始删除几个(可能是零或全部)元素和从结束删除几个(可能是零或全部)元素来获得。

    如果该数组的每个非空子数组,该子数组的元素的和都是非零,则我们称非空数组为good。例如,数组[−1,2,−3]是好的,因为所有数组[−1],[−1,2],[−1,2,−3],[2],[2,−3],[−3]的元素和都是非零的。但是,数组[- 1,2,- 1,- 3]并不好,因为它的子数组[- 1,2,- 1]的元素和为0。

    帮助Eugene计算一个给定数组a的非空良子数组的数目。

    输入

    输入的第一行包含一个整数n(1≤n≤2×105)——数组a的长度。

    输入的第二行包含n个整数a1,a2,…,an(−109≤ai≤109)- a的元素。

    输出

    输出一个整数——a的好子数组的数目。

    例子

    inputCopy

    3.

    1 2 3

    outputCopy

    5

    inputCopy

    3.

    41 -41 41

    outputCopy

    3.

    请注意

    在第一个样本中,下列子阵列是良好的:[1],[1,2],[2],[2,−3],[−3]。然而,子数组[1,2,−3]并不好,因为它的子数组[1,2,−3]的元素和等于0。

    在第二个示例中,大小为1的三个子数组是惟一的好子数组。与此同时,子数组[41,−41,41]并不好,因为它的子数组[41,−41]的元素和等于0。

    题解:

    从左往右遍历,用一个map存储当前前缀和的值是否在之前出现过。如果出现过,那么之前的位置到当前的位置的这段序列是不合法的,根据这个方法可以统计出正确答案,时间复杂度是O(N)

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=2e5+100;
    int a[maxn];
    map<ll,ll> pos;
    int main () {
        int N;
        scanf("%d",&N);
        pos[0]=1;
        ll sum=0,ans=0,Max=1;
        for (int i=2;i<=N+1;i++) {
            scanf("%d",&a[i]);
            sum+=a[i];
            if (pos[sum]!=0) 
                Max=max(Max,pos[sum]+1);
            ans+=i-Max;
            pos[sum]=i;
        }
        printf("%lld
    ",ans);
    }
  • 相关阅读:
    我的第一个开源项目
    读headFirst设计模式
    读headFirst设计模式
    读headFirst设计模式
    eclipse中svn插件的安装和tortoiseSVN的安装
    读headFirst设计模式
    浅析博客园的保存密码并自动登录, 然后自己写一个demo
    java中易遗忘的知识,不定时更新……
    POI操作Excel
    java泛型基础
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/12687337.html
Copyright © 2011-2022 走看看