bzoj3771: Triple

10:(5,5),(4,6),(6,4) 再+8

12:(6,6),(4,8),(8,4) 再+6

13:(5,8),(8,5) 再+5

14:(6,8),(8,6) 再+4

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
const double pi=acos(-1.0);

struct Complex
{
double r,i;
Complex(){r=0, i=0;}
Complex(double _r,double _i){r=_r, i=_i;}
friend Complex operator +(Complex x,Complex y){return Complex(x.r+y.r,x.i+y.i);}
friend Complex operator -(Complex x,Complex y){return Complex(x.r-y.r,x.i-y.i);}
friend Complex operator *(Complex x,Complex y){return Complex(x.r*y.r-x.i*y.i,x.r*y.i+x.i*y.r);}
}T[410000],A[410000],B[410000];
int d[410000],d2[410000],len;

int R[410000];
void fft(Complex *a,int n,int op)
{
for(int i=0;i<n;i++)
if(i<R[i])swap(a[i],a[R[i]]);

for(int i=1;i<n;i*=2)
{
Complex wn(cos(pi/i),sin(pi*op/i));
for(int j=0;j<n;j+=(i<<1))
{
Complex w(1,0);
for(int k=0;k<i;k++,w=w*wn)
{
Complex a1=a[j+k],a2=a[j+k+i];
a[j+k]  =a1+w*a2;
a[j+k+i]=a1-w*a2;
}
}
}
}

void FFT1(int n,int m)
{
int nn=n,L=0;
for(int i=0;i<=n;i++)A[i].r=B[i].r=T[i].r;
m=m+n;for(n=1;n<=m;n*=2)L++;
for(int i=0;i<n;i++)R[i]=(R[i>>1]>>1)|((i&1)<<(L-1));

fft(A,n,1);fft(B,n,1);
for(int i=0;i<n;i++)A[i]=A[i]*B[i], B[i].r=0, B[i].i=0;

fft(A,n,-1);
for(int i=0;i<n;i++)
A[i].r=int(A[i].r/n+0.5), A[i].i=0;

for(int i=1;i<n;i++)A[i].r/=2;

for(int i=0;i<n;i++)d[i]+=int(A[i].r), A[i].r=0, A[i].i=0;
len=m;
//第一次FFT，解决用1/2个不同物品组成不同价值
}
void FFT2(int n,int m)
{
int nn=n,L=0;
for(int i=0;i<=n;i++)A[i].r=B[i].r=T[i].r;
m=m+n;for(n=1;n<=m;n*=2)L++;
for(int i=0;i<n;i++)R[i]=(R[i>>1]>>1)|((i&1)<<(L-1));

fft(A,n,1);fft(B,n,1);
for(int i=0;i<n;i++)A[i]=A[i]*B[i], B[i].r=0, B[i].i=0;

fft(A,n,-1);
for(int i=0;i<n;i++)
{
A[i].r=int(A[i].r/n+0.5), A[i].i=0;
//        if(int(A[i].r)!=0)printf("%d %d\n",i,int(A[i].r));
}
//    printf("\n");

n=nn;L=0;
for(int i=0;i<=n;i++)B[i].r=T[i].r;
m=m+n;for(n=1;n<=m;n*=2)L++;
for(int i=0;i<n;i++)R[i]=(R[i>>1]>>1)|((i&1)<<(L-1));

fft(A,n,1);fft(B,n,1);
for(int i=0;i<n;i++)A[i]=A[i]*B[i], B[i].r=0, B[i].i=0;

fft(A,n,-1);
for(int i=0;i<n;i++)
{
A[i].r=int(A[i].r/n+0.5), A[i].i=0;
//        if(int(A[i].r)!=0)printf("%d %d\n",i,int(A[i].r));
}
//    printf("\n");

for(int i=0;i<n;i++)d2[i]+=int(A[i].r), A[i].r=0, A[i].i=0;
len=m;

//    for(int i=0;i<=len;i++)
//    if(d[i]!=0)printf("%d %d\n",i,d[i]);
}
void FFT3(int n,int m)
{
int nn=n,L=0;
for(int i=0;i<=n;i++)A[i+i].r=B[i].r=T[i].r;

m=m+n;for(n=1;n<=m;n*=2)L++;
for(int i=0;i<n;i++)R[i]=(R[i>>1]>>1)|((i&1)<<(L-1));

/*    for(int i=0;i<n;i++)
if(int(A[i].r)!=0)printf("%d %d\n",i,int(A[i].r));
for(int i=0;i<n;i++)
if(int(B[i].r)!=0)printf("%d %d\n",i,int(B[i].r));
*/
fft(A,n,1);fft(B,n,1);
for(int i=0;i<n;i++)A[i]=A[i]*B[i], B[i].r=0, B[i].i=0;

fft(A,n,-1);
for(int i=0;i<n;i++)
A[i].r=int(A[i].r/n+0.5), A[i].i=0;

//    for(int i=0;i<n;i++)
//        if(int(A[i].r)!=0)printf("%d %d\n",i,int(A[i].r));

for(int i=0;i<n;i++)d2[i]-=int(A[i].r)*3, A[i].r=0, A[i].i=0;

for(int i=1;i<=len;i++)
{
d2[i]/=6;d2[i]+=d[i];
if(d2[i]!=0)
printf("%d %d\n",i,d2[i]);
}
}
int main()
{
//    freopen("f.in","r",stdin);
//    freopen("f.out","w",stdout);
int n,x,mx=0;
scanf("%d",&n);
memset(d,0,sizeof(d));
memset(d2,0,sizeof(d2));
for(int i=1;i<=n;i++)
{
scanf("%d",&x);
T[x].r++;d2[x+x+x]+=2;
mx=max(mx,x);
}
T[0].r=1;FFT1(mx,mx);
T[0].r=0;FFT2(mx,mx);
FFT3(mx*2,mx);
return 0;
}

pain and happy in the cruel world.
posted @ 2017-12-09 11:48  AKCqhzdy  阅读(131)  评论(0编辑  收藏  举报