链接:
https://codeforces.com/problemset/problem/466/C
题意
给你一个长度为n的数组,问有几种方式可以把数组分成连续的三个部分,且每个部分内的和相等。
1 ≤ n ≤ 5e5
|a[i]| ≤ 109
Example
input
5
1 2 3 0 3
output
2
input
4
0 1 -1 0
output
1
2
4 1
0
解析
这题将数组分成总和相等的三部分,那每部分的和就是数组总和的1/3,所以先判断数组和是否为三的倍数,如果是,将数组进行前缀和处理,然后将其分成三个部分,第一部分就是值为1/3,第二部分就是值为2/3,剩下的就是第三部分,其实多少中方法就是取决于有第一部分和第二部分有多少种,例如:
#include <iostream>
using namespace std;
typedef long long ll;
const int N = 5e5 + 10;
int n;
ll a[N], s[N], sum;
int main()
{
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
sum += a[i];
}
//处理前缀和
for (int i = 1; i <= n; i++) s[i] = s[i - 1] + a[i];
if (sum % 3 != 0 || n < 3) cout << 0;
else
{
sum /= 3;
ll point1_num = sum;
ll point2_num = sum * 2;
ll point1 = 0, point2 = 0;
for (int i = 1; i < n; i++)//没有到最后一个,最后一个是sum*3
{
if (s[i] == point2_num) point2 += point1;
if (s[i] == point1_num) point1++;
}
cout << point2;
}
return 0;
}