题解:P12708 [KOI 2021 Round 1] 分割
题意
求出把一个序列划分为四段非空且相等的连续段的方案数。
思路
我们将形式化题意中的
既然要四段都相等,那么一段的总和应该为序列总和的四分之一。而且第一、二段的总和应该和第三、四段的总和相等,且为序列总和的一半。我们记录序列前缀和和后缀和,找到前缀和等于序列总和的四分之一的位置当
预处理
代码
思路不难,预处理有些细节需要注意,别忘了特判即可。
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,a[100005],sum=0,pre[100005],suf[100005],ans=0;
signed main() {
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i],sum+=a[i];
if(sum%4)return cout<<0,0;
int tmp=0;
for(int i=2;i<=n;i++){
tmp+=a[i-1];
if(tmp==sum/4)pre[i]=pre[i-1]+1;
else pre[i]=pre[i-1];
}
tmp=0;
for(int i=n-1;i>=1;i--){
tmp+=a[i+1];
if(tmp==sum/4)suf[i]=suf[i+1]+1;
else suf[i]=suf[i+1];
}
tmp=0;
for(int i=1;i<=n-1;i++){
tmp+=a[i];
if(tmp==sum/2)ans+=pre[i]*suf[i+1];
}
cout<<ans;
return 0;
}