SPOJ - TSUM Triple Sums FFT+容斥
阿新 • • 發佈:2017-07-01
tex 分享 con size 題解 pair const ati print Each of the next N lines contain an element of s.
7 can be obtained using triples ( 0, 2, 4 ) and ( 1, 3, 4 ).
Note: a triple is considered the same as any of its permutations.
Triple Sums
You‘re given a sequence s of N distinct integers.
Consider all the possible sums of three integers from the sequence at three different indicies.
For each obtainable sum output the number of different triples of indicies that generate it.
Constraints:
N <= 40000, |si| <= 20000
Input
The first line of input contains a single integer N.
Output
Print the solution for each possible sum in the following format:
sum_value : number_of_triples
Smaller sum values should be printed first.
Example
Input:
5
-1
2
3
0
5
Output:
1 : 1
2 : 1
4 : 2
5 : 1
6 : 1
7 : 2
8 : 1
10 : 1
Explanation:
4 can be obtained using triples ( 0, 1, 2 ) and ( 0, 3, 4 ).
Note: a triple is considered the same as any of its permutations.
題意:
給你n個數,問你任選三個不同序號的數和為x的方案數有多少
題解:
FFT;
容斥原理要學好
#include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define ls i<<1 #definers ls | 1 #define mid ((ll+rr)>>1) #define pii pair<int,int> #define MP make_pair typedef long long LL; const long long INF = 1e18+1LL; const double pi = acos(-1.0); const int N = 5e5+10, M = 1e3+20,inf = 2e9,mod = 1e9+7; struct Complex { double r , i ; Complex () {} Complex ( double r , double i ) : r ( r ) , i ( i ) {} Complex operator + ( const Complex& t ) const { return Complex ( r + t.r , i + t.i ) ; } Complex operator - ( const Complex& t ) const { return Complex ( r - t.r , i - t.i ) ; } Complex operator * ( const Complex& t ) const { return Complex ( r * t.r - i * t.i , r * t.i + i * t.r ) ; } } ; void FFT ( Complex y[] , int n , int rev ) { for ( int i = 1 , j , t , k ; i < n ; ++ i ) { for ( j = 0 , t = i , k = n >> 1 ; k ; k >>= 1 , t >>= 1 ) j = j << 1 | t & 1 ; if ( i < j ) swap ( y[i] , y[j] ) ; } for ( int s = 2 , ds = 1 ; s <= n ; ds = s , s <<= 1 ) { Complex wn = Complex ( cos ( rev * 2 * pi / s ) , sin ( rev * 2 * pi / s ) ) , w ( 1 , 0 ) , t ; for ( int k = 0 ; k < ds ; ++ k , w = w * wn ) { for ( int i = k ; i < n ; i += s ) { y[i + ds] = y[i] - ( t = w * y[i + ds] ) ; y[i] = y[i] + t ; } } } if ( rev == -1 ) for ( int i = 0 ; i < n ; ++ i ) y[i].r /= n ; } int num[N],n,x,now[N]; Complex s[N*8],t[N*8],tt[N]; int main() { scanf("%d",&n); for(int i = 1; i <= n; ++i) { scanf("%d",&x); num[x + 20000]++; } int n1; for(int i = 1; i <= 20000*6; i<<=1,n1=i); for(int i = 0; i <= 20000*2; ++i) now[i+i] += num[i]; for(int i = 0; i <= 20000*4; ++i) s[i] = Complex(now[i],0); for(int i = 20000*4+1; i < n1; ++i) s[i] = Complex(0,0); for(int i = 0; i <= 2*20000; ++i) t[i] = Complex(num[i],0); for(int i = 2*20000+1; i < n1; ++i) t[i] = Complex(0,0); for(int i = 0; i < n1; ++i) tt[i] = t[i]; FFT(s,n1,1),FFT(t,n1,1);FFT(tt,n1,1); for(int i = 0; i < n1; ++i) t[i] = t[i]*t[i]*t[i]; for(int i = 0; i < n1; ++i) s[i] = s[i]*tt[i]; FFT(s,n1,-1),FFT(t,n1,-1); int cnt = 0; for(int i = 0; i <= 6*20000; ++i) { int x = ((int)(t[i].r + 0.5)) - 3*((int)(s[i].r+0.5)); if(i%3==0) x += 2*num[i/3]; x/=6; if(x) { printf("%d : %d\n",i - 3*20000,x); } } return 0; }
SPOJ - TSUM Triple Sums FFT+容斥