Eugene and an array

Eugene and an array

Eugene and an array 题目链接

思路

考察的是前缀和的应用,我们假定\(sum_i == sum_j\)哪么一定有\(\sum\limits_{k = i + 1} ^ {j}a_k= 0\)

我们从\(1 -> n\)每次计算符合要求的以当前的点为终点的子序列的数量,定一个标记p,表示最后出现\(sum_i == sum_j,i\) 的位置\(\sum\limits_{k = i + 1} ^ {j}a_K= 0\),我们舍弃第 \(i + 1\) 位那么从\(p + 2 -> now\)中所有子序列的值一定不存在和为0的情况,所以其中的子序列的数量就是\(now - (p + 1)\)

接下来有一个需要特别判断的情况,也就是初始情况,我们要让\(p = -1, mp[0] = 0\),这样就可以保证第一个数的时候是\(1 - (-1) - 1 = 1\),然后对于p我们要注意一定要是取当前最大的一个,所以每次需要判断是否是最大的。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
map<LL, int> mp;
int main() {
    // freopen("in.txt", "r", stdin);
    ios::sync_with_stdio(false);
    int n, p = 0;
    cin >> n;
    mp[0] = 1;
    LL sum = 0, a, ans = 0;//为了方便if(mp[sum])判断,这里把整个数组向右移了一位,
    for(int i = 2; i <= n + 1; i++) {//所以mp[0] = 1, p = 0,都向右移了一位。
        cin>> a;
        sum += a;
        if(mp[sum]) p = max(p, mp[sum]);
        ans += i - p - 1;
        mp[sum] = i;
        // cout << ans << endl;
    }
    cout << ans << endl;
    return 0;
}
posted @ 2020-04-30 15:26  lifehappiness  阅读(103)  评论(0编辑  收藏  举报