涉及知识点:
solution:
- \(题意简单概括为,给出数组a,让你找到所有的b数组,b数组需要满足两个条件:\)
- \(条件1,b数组是a数组的子数组(要求连续)\)
- \(条件2,b数组的子数组(要求连续)之和不等于0\)
- \(n = 1e5 , 暴力不可解\)
- \(子数组因为是连续的,假设[1,x]的和为a,[1,y]的和也为a,那就说明[x+1,y]这段子数组和为0\)
- $根据这个特点,固定右端点y,我们只能取左端点为x+2,x+3,x+4......y $
- \(因为如果取左端点为x+1或者更小,[x+1,y]这段子数组和为0,不满足条件\)
- \(所以做法就是:O(n)枚举每一个右端点,用map存一下前缀和,记录一下左端点的最大值,更新答案\)
std:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 200005;
ll a[maxn],pre[maxn];
int main()
{
int n , l = 0;
ll ans = 0;
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i],pre[i] = pre[i-1] + a[i];
map<ll , int > mp;
mp[0] = 0;
for(int i=1;i<=n;i++){
if(mp[pre[i]] || pre[i] == 0)
l = max(l , mp[pre[i]] + 1);
ans += 1ll*(i - l);
mp[pre[i]] = i;
}
cout<<ans<<endl;
return 0;
}