Number of Ways
题意:将一个数组分成连续的三段,有几种分法可以使三段和相等
分析:
因为要求和,所以肯定要前缀和(雾),遍历数组,如果当前和等于sun[n]/3,则这个位置可以为i,如果当前和等于sum[n]/3*2,则这个位置可以为j,答案加上这之前可以为i的数量(好像也不算是双指针吧)
Code:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int, int>
#define mem(a, b) memset(a, b, sizeof(a));
#define lowbit(x) (x & -x)
#define lrt nl, mid, rt << 1
#define rrt mid + 1, nr, rt << 1 | 1
template <typename T>
inline void read(T& t) {
t = 0;
int f = 1;
char ch = getchar();
while (!isdigit(ch)) {
if (ch == '-')
f = -1;
ch = getchar();
}
while (isdigit(ch)) {
t = t * 10 + ch - '0';
ch = getchar();
}
t *= f;
}
const int dx[] = {0, 1, 0, -1};
const int dy[] = {1, 0, -1, 0};
const ll Inf = 9223372036854775807;
const int inf = 0x3f3f3f3f;
const double eps = 1e-5;
const int maxn = 5e5 + 5;
int an[maxn];
ll sum[maxn];
int main(void) {
int n;
read(n);
for (int i = 1; i <= n; i++) {
read(an[i]);
sum[i] = sum[i - 1] + (ll)an[i];
}
if (sum[n] % 3)
printf("0\n");
else {
ll ans = 0, k = sum[n] / 3, res = 0;
for (int i = 1; i <= n; i++) {
if (i > 1 && i < n && sum[i] == 2 * k)
ans += res;
if (sum[i] == k)
res++;
}
printf("%lld\n", ans);
}
return 0;
}