題目:
樣例:
題目大意:
給一個數組序列,問子串的和不爲 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 的用法更加深了了解。
仍是學的了不少東西,加油。