/*本题主要是按照前n项和来判断切分点,按照前n项中的正整数个数来判定各个分组中至少有一个正整数。*/
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
long long pre[200010]; //pre是前n项和
int pos[200010]; //pos是前n项中的正整数个数
int i_p[200010],j_p[200010]; //i_p是i的可能存在的位置数组,j_p是j可能存在的位置数组
int cnt_i,cnt_j; //cnt_i是i可能存在的个数cnt_j是j可能存在的个数
int data[200010]; //存放i切点前的正整数个数
//qsort的排序函数,从小到大
int cmp(const void *a,const void *b){
return *(int*)a-*(int*)b;
}
//二分查找比目标c小的个数
int midfound(int *a,int b,int c){
int left=0;
int right=b;
while (left<right) {
int mid=(left+right)/2;
if (a[mid]<c) {
left=mid+1;
}
else {
right=mid;
}
}
return left;
}
int main() {
int a;
int n;
scanf("%d",&n);
// 计算前n项和以及前n项正整数个数
for (int i=0; i<n; i++) {
scanf("%d",&a);
if (i==0) {
pre[i]=a;
if (a>0) {
pos[i]=1;
}
}
else {
pre[i]=pre[i-1]+a;
if (a>0) {
pos[i]=pos[i-1]+1;
}
else {
pos[i]=pos[i-1];
}
}
}
//如果总和不能被3整除则说明不能分成三组直接输出0
if (pre[n-1]%3!=0) {
printf("0");
return 0;
}
a=pre[n-1]/3;
//计算i的位置的可能性并将i的位置存放在数组i_p中,i最多只能到n-3需要至少留有2个元素位置给后面两段
cnt_i=0;
for (int i=0; i<n-2; i++) {
if (pre[i]==a&&pos[i]>0) {
i_p[cnt_i++]=i;
}
}
//计算j的位置的可能性并将j的位置存放在数组j_p中,j最小是1需要给第一段至少一个数字,最大是n-2至少留一个数字给最后一段
cnt_j=0;
for (int j=1; j<n-1; j++) {
if (pre[j]==2*a&&pos[j]<pos[n-1]) {
j_p[cnt_j++]=j;
}
}
//判断方案是否可行
long long d=0;
int p=0;
int b=0;
//遍历所有的第二切点j的位置
for (int i=0; i<cnt_j; i++) {
//当i的位置在j位置之前且未遍历完所有的i的位置时将i的位置之前的所有正整数个数存在数组中
while (p<cnt_i&&i_p[p]<j_p[i]) {
data[b++]=pos[i_p[p]];
p++;
}
//将所有的正整数数组按从小到大排列
qsort(data, b, sizeof(int), cmp);
//用二分查找找出所有data中小于pos[j_p[i]]的值,即第一段的正整数个数小于前两段正整数个数的和。将总个数相加。
d+=midfound(data,b,pos[j_p[i]]);
}
//遍历完所有切点j也就遍历完了所有切点i,所有符合条件的切点相加即切点方案数,直接输出
printf("%lld",d);
return 0;
}