[每日一题]:Codeforces Round #632 (Div. 2) C. Eugene and an array

题目:

样例:

题目大意:

给一个数组序列,问子串的和不为 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 的用法更加深了了解。
还是学的了很多东西,加油。
posted @ 2020-04-10 23:16  IceSwords  阅读(106)  评论(0编辑  收藏  举报