题目:
样例:
题目大意:
给一个数组序列,问子串的和不为 0 的数量。(子串是连续的哦)
考察点:
前缀和、尺取、set的用法、思维
图解:
Code:
#include <set>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn = 2e5 + 10;
LL a[maxn],pre[maxn];
LL n,res = 0;
set<LL>sets;
int main(void) {
scanf("%lld",&n);
for(int i = 1; i <= n; i ++) {
scanf("%lld",&a[i]);
pre[i] = pre[i - 1] + a[i];
}
int start = 0,end = 0;
// 方便和 0 进行配对 0 - 0 = 0
sets.insert(0);
// 尺取进行枚举
while(start <= n) {
// 前缀和相等的值,相减为 0 ,说明这个区间再大就不可取了
// 直到没有重复的才会向后移动,有重复的说明 start(包括 Start 最多只能和 end 前一个组成子区间)
while(end < n && !sets.count(pre[end + 1])) {
end ++;
sets.insert(pre[end]);
}
res += end - start;
// 枚举下一个,枚举之前先删掉前面的(防止和后面的重复)
sets.erase(pre[start]);
start ++;
}
printf("%lld\n",res);
return 0;
}
客官留步:
前缀和的性质想到了,但是尺取区间想的不是太到位。
对 set 的用法更加深了了解。
还是学的了很多东西,加油。
原文地址:https://www.cnblogs.com/prjruckyone/p/12676961.html
时间: 2024-11-06 07:40:11