AcWing_3956 截断数组(前缀和)

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;
}