【模板】快速傅里叶变换

uoj34

 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 }

 

posted @ 2018-03-20 21:00  Cupcake  阅读(155)  评论(0编辑  收藏  举报