码迷,mamicode.com
首页 > 其他好文 > 详细

SPOJ - TSUM Triple Sums FFT+容斥

时间:2017-07-01 18:30:30      阅读:206      评论:0      收藏:0      [点我收藏+]

标签:number   nbsp   from   return   next   printf   fine   image   include   

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.
Each of the next N lines contain an element of s.

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 ).
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.

 

题意:

  给你n个数,问你任选三个不同序号的数和为x的方案数有多少

题解:

  FFT;

  容斥原理要学好

  技术分享

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define ls i<<1
#define rs 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+容斥

标签:number   nbsp   from   return   next   printf   fine   image   include   

原文地址:http://www.cnblogs.com/zxhl/p/7102937.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!