模板 FFT 快速傅里叶变换

FFT模板,原理不难,优质讲解很多,但证明很难看太不懂

这模板题在bzoj竟然是土豪题,服了

 1 #include <cmath>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #define dd double 
 6 #define ll long long
 7 #define N (1<<21)+10
 8 using namespace std;
 9 
10 int n,m,ma;
11 int r[N];
12 dd const pi=acos(-1);
13 struct cp{
14     dd x,y;
15     cp(dd a,dd b):x(a),y(b){}
16     cp(){}
17     cp operator+(const cp &a){return cp(x+a.x,y+a.y);}
18     cp operator-(const cp &a){return cp(x-a.x,y-a.y);}
19     cp operator*(const cp &a){return cp(x*a.x-y*a.y,x*a.y+y*a.x);}
20 }a[N],b[N],c[N];
21 void FFT(cp s[],int len,int type)
22 {
23     for(int i=0;i<len;i++)
24         if(i<r[i]) swap(s[i],s[r[i]]);
25     for(int k=2;k<=len;k<<=1)
26     {
27         cp wn(cos(2*pi*type/k),sin(2*pi*type/k));
28         for(int i=0;i<len;i+=k)
29         {
30             cp t,w(1,0);
31             for(int j=0;j<(k>>1);j++,w=w*wn)
32             {
33                 t=w*s[i+j+(k>>1)];
34                 s[i+j+(k>>1)]=s[i+j]-t;
35                 s[i+j]=s[i+j]+t;
36             }
37         }
38     }
39 }
40 void FFT_main(cp A[],cp B[],cp C[],int len)
41 {
42     FFT(A,len,1);FFT(B,len,1);
43     for(int i=0;i<len;i++) C[i]=A[i]*B[i];
44     FFT(C,len,-1);
45 }
46 
47 int gc()
48 {
49     int rett=0,fh=1;char c=getchar();
50     while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();}
51     while(c>='0'&&c<='9'){rett=(rett<<3)+(rett<<1)+c-'0';c=getchar();}
52     return rett*fh;
53 }
54 
55 int main()
56 {
57     n=gc(),m=gc(),ma=0,n++,m++;
58     for(int i=0;i<n;i++) a[i].x=1.0*gc();
59     for(int i=0;i<m;i++) b[i].x=1.0*gc();
60     while((1<<ma)<n+m){ma++;}
61     for(int i=0;i<(1<<ma);i++) 
62         r[i]=(r[i>>1]>>1)|((i&1)<<(ma-1));
63     FFT_main(a,b,c,1<<ma);
64     for(int i=0;i<n+m-1;i++) printf("%d ",(int)(c[i].x/(1<<ma)+0.1));
65     return 0;
66 }
原文地址:https://www.cnblogs.com/guapisolo/p/9697109.html