bzoj2194: 快速傅立叶之二
了解到了FFT求卷积,但是还是感性的认识。。
取反就可以了。输出一定要加int!!!!
#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(){} 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);} }A[410000],B[410000],C[410000]; 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; } } } if(op==-1)for(int i=0;i<n;i++)a[i].r/=n; } int main() { int n,m,L=0; scanf("%d",&m);m--; for(int i=0;i<=m;i++)scanf("%lf%lf",&A[i].r,&B[m-i].r); m*=2;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++)C[i]=A[i]*B[i]; fft(C,n,-1); for(int i=m/2;i<=m;i++) printf("%d\n",int(C[i].r+0.5)); return 0; }
pain and happy in the cruel world.