C. Number of Ways(前缀和)
题意:给出n个数,问分成3组数且每组数和相等,(不改变原数列顺序)有几种分法。
题解:先求数列总和,判断这个数列是否能分成大小相等的3份。能的话,可以从后往前找,把遇到的和满足条件的标记一下。再从后往前,用前缀和的方式,把分法个数加起来,(说明在这个数之后,能够找到的分法和)然后再从前往后,找到满足条件的和,然后找到i+2位置上的分法和。(为什么是i+2?如果是i+1的话,可能后面就只有一个数了,会不满足分成3组的条件)。
ACcode:
ll n,a[500010],ans=0;
ll Sum, cnt[500010];
int main()
{
memset(cnt, 0, sizeof(cnt));//清0
Sum = 0;
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> a[i];
Sum += a[i];
}//求总和
if (Sum % 3 != 0)
cout << "0"<<endl;//不满足条件,跳出
else
{
ll s = 0;
Sum = Sum / 3;
for (int i = n-1; i >=0; i--)
{
s += a[i];
if (s == Sum)
cnt[i]++;//满足条件则标记
}
for (int i = n - 1; i >= 0; i--)
{
cnt[i] += cnt[i + 1];//把分法和都加起来
}
s = 0;
for (int i = 0; i < n; i++)
{
s += a[i];
if (s ==Sum)
ans += cnt[i+ 2];
}//遇到满足条件,就去查询i+2位置上的分法
cout << ans<<endl;
}
return 0;
}