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;
}