1. 程式人生 > >Number of Ways

Number of Ways

Description

You've got array a[1], a[2], ..., a[n], consisting of n integers. Count the number of ways to split all the elements of the array into three contiguous parts so that the sum of elements in each part is the same.

More formally, you need to find the number of such pairs of indices i, j(2 ≤ i

 ≤ j ≤ n - 1), that .

Input

The first line contains integer n(1 ≤ n ≤ 5·105), showing how many numbers are in the array. The second line contains n integersa[1]a[2], ..., a[n](|a[i]| ≤  109) — the elements of array a.

Output

Print a single integer — the number of ways to split the array into three parts with the same sum.

Sample Input

Input
5
1 2 3 0 3
Output
2
Input
4
0 1 -1 0
Output
1
Input
2
4 1
Output

0

題意:

給一個長度為n的陣列,將其分成連續的三段使三段的和相等,求有幾種這樣的組合

分析:

從頭掃到尾,將所有的字首和為(sum/3)的點統計起來,然後再從尾開始統計,找到統計所有後綴和為(sum/3)的節點 然後這種方案的數為

這個點之前所有字首和為sum/3的個數


#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=500010;
long long e[maxn];
int cnt[maxn];
int main(){
	int n;
	while(~scanf("%d",&n)){
		memset(cnt,0,sizeof(cnt));
		long long s=0,p=0;
		for(int i=1;i<=n;i++){
			scanf("%lld",&e[i]);
		    s+=e[i];
		}
		if(s%3){
			printf("0\n");
			continue;
		}
		s/=3;
		int num=0;
		for(int i=1;i<=n;i++){
			p+=e[i];
			if(p==s){
				cnt[num++]=i;
			}
		}
		p=0;
		long long ans=0;
		for(int i=n;i>=1;i--){
			p+=e[i];
			if(p==s){
				//返回第一個小於等於i-1的值 
				int pos=lower_bound(cnt,cnt+num,i-1)-cnt;
			//	printf("%d***%d\n",i-1,pos);
				ans+=pos;
			}
		}
		cout << ans << endl;
	}
	return 0;
}