AcWing
3956. 截断数组
前缀和数组。使用数组s
维护前缀和,从前到后遍历第二刀的位置,在遍历的同时更新第一刀到起点之间和为sum/3
的前缀选法个数cnt
,即本次第二刀位置的情况下,第一刀的选法种类数;如果这个时候第二刀的位置到终点的和是sum/3
,那么结果数组res+=cnt
。
注意结果数组要开long long
,因为选法最多有$C_{n-1}^2\sim 10^{10}$种,int的范围(abs)约在$2*10^9$.
#include <bits/stdc++.h>
using namespace std;
vector<int> s;
int main(){
int n;
cin >> n;
s.resize(n + 1);
for(int i = 1; i <= n; i++){ // 前缀和数组
cin >> s[i];
s[i] += s[i - 1];
}
if(s[n] % 3 != 0){
cout << 0 << endl;
return 0;
}
long long res = 0;
for(int i = 3, cnt = 0; i <= n; i++){
if(s[i - 2] == s[n] / 3) cnt++;
if(s[n] - s[i - 1] == s[n] / 3) res += cnt;
}
cout << res << endl;
return 0;
}