【模板】快速傅里叶变换
1 #include<bits/stdc++.h> 2 #define db double 3 using namespace std; 4 const int N=400010; 5 const db PI=acos(-1); 6 int n,m,tot,maxp,rev[N]; 7 struct Com{ 8 db real,image; 9 Com operator+(const Com& k)const{return (Com){real+k.real,image+k.image};}; 10 Com operator-(const Com& k)const{return (Com){real-k.real,image-k.image};}; 11 Com operator*(const Com& k)const{return (Com){real*k.real-image*k.image,real*k.image+image*k.real};}; 12 Com operator/(const int k)const{return (Com){real/k,image/k};}; 13 }a[N],b[N]; 14 void fft(Com* a,int b){ 15 for(int i=0;i<n;i++) if(rev[i]>i) swap(a[i],a[rev[i]]); 16 for(int len=2;len<=n;len<<=1){ 17 Com wn=(Com){cos(2.0*PI/len),sin(2.0*PI/len)*b}; 18 for(int i=0;i<n;i+=len){ 19 Com w=(Com){1,0}; 20 for(int j=0;j<(len>>1);j++,w=w*wn){ 21 Com x=a[i+j],y=a[i+j+(len>>1)]*w; 22 a[i+j]=x+y,a[i+j+(len>>1)]=x-y; 23 } 24 } 25 } 26 if(b==-1) for(int i=0;i<n;i++) a[i]=a[i]/n; 27 return; 28 } 29 int main(){ 30 scanf("%d%d",&n,&m); 31 for(int i=0;i<=n;i++) scanf("%lf",&a[i].real); 32 for(int i=0;i<=m;i++) scanf("%lf",&b[i].real); 33 tot=n+m,n=1; 34 while(n<=tot) n<<=1,maxp++; 35 for(int i=1;i<n;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(maxp-1)); 36 fft(a,1);fft(b,1); 37 for(int i=0;i<n;i++) a[i]=a[i]*b[i]; 38 fft(a,-1); 39 for(int i=0;i<=tot;i++) printf("%d ",int(a[i].real+0.1)); 40 return 0; 41 }