C. Eugene and an array
题目链接-C. Eugene and an array


题目大意
数组内和不为
0
0
0的连续子序列被称为好的序列,统计数组
a
n
an
an 中有几个好的序列
解题思路
前
缀
和
+
计
数
前缀和+计数
前缀和+计数
- 求出前缀和,前缀和 p r e [ i ] = p r e [ j ] pre[i]=pre[j] pre[i]=pre[j]意味着 a [ i + 1 ] − a [ j ] a[i+1]-a[j] a[i+1]−a[j] 这一段的和为 0 0 0
map维护当前出现过的前缀和的下标,即用map记录 s u m sum sum上一次出现的位置,即左端点- 用 k k k来记录当前没有前缀和为 0 0 0的区间的左端点(左端点最大值),以当前点 i i i为右端点,因为区间为左开右闭,所以 k k k要初始化为 1 1 1
- 所以满足条件的区间就是 ( k , i ] (k,i] (k,i],然后区间内数的个数就是增加当前这个点后增加的好序列个数,即不包含子串和为 0 0 0的个数为 i − ( k + 1 ) i−(k+1) i−(k+1),累加即可
- 具体操作见代码
附上代码
#pragma GCC optimize("-Ofast","-funroll-all-loops")
//#pragma GCC diagnostic error "-std=c++11"
#include<bits/stdc++.h>
#define int long long
#define lowbit(x) (x &(-x))
#define endl '\n'
using namespace std;
const int INF=0x3f3f3f3f;
const int dir[4][2]={-1,0,1,0,0,-1,0,1};
const double PI=acos(-1.0);
const double e=exp(1.0);
const double eps=1e-10;
const int M=1e9+7;
const int N=1e5+10;
typedef long long ll;
typedef pair<int,int> PII;
typedef unsigned long long ull;
map<int,int> mp;
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
mp[0]=0;//第一个数前面前缀和为0
int n,ans=0,tmp=0,k=-1;
cin>>n;
for(int i=1;i<=n;i++){
int t;
cin>>t;
tmp+=t;//记录前缀和
if(mp.count(tmp))//判断tmp是否出现过
//因为初始化mp[0]=0,所以用if(mp[tmp])判断会出错
k=max(k,mp[tmp]);
ans+=i-k-1;//注意边界问题
mp[tmp]=i;
}
cout<<ans<<endl;
return 0;
}
1343

被折叠的 条评论
为什么被折叠?



