模板—FFT

卷积:$C[i]=\sum \limits_{j=0}^{i}A[j]*B[i-j]$可以画图理解一下其实就是交叉相乘的和。

卷积可以看作两个多项式乘积的形式,只不过求出的结果的项数不同。

FFT讲解

复数讲解

 1 #include<iostream>
 2 #include<cstring>
 3 #include<complex>
 4 #include<cstdio>
 5 #define cp complex<double>
 6 using namespace std;
 7 const double pi=3.14159265358979;
 8 
 9 void FFT(cp *a,int n,int inv)
10 {    
11     if(n==1)return;
12     int mid=n/2;static cp b[1000100];
13     for(int i=0;i<=mid-1;i++)b[i]=a[i*2],b[i+mid]=a[i*2+1];
14     for(int i=0;i<=n-1;i++)a[i]=b[i];
15     FFT(a,mid,inv);FFT(a+mid,mid,inv);
16     for(int i=0;i<=mid-1;i++)
17     {
18         cp x(cos(2*pi*i/n),inv*sin(2*pi*i/n));
19         b[i]=a[i]+x*a[i+mid],b[i+mid]=a[i]-x*a[i+mid];
20     }
21     for(int i=0;i<=n-1;i++)a[i]=b[i];
22 }
23 int n,m;
24 cp a[1000010],b[1000010];int c[1000010];
25 signed main()
26 {
27 //    freopen("1.in","r",stdin);
28 //    freopen("out.out","w",stdout);
29 
30     cin>>n>>m;double tem;
31     for(int i=0;i<=n;i++)scanf("%lf",&tem),a[i]=cp(tem,0);
32     for(int i=0;i<=m;i++)scanf("%lf",&tem),b[i]=cp(tem,0);
33     int len=n+m+1,now=1;
34     for(;;now*=2)if(now>=len){len=now;break;}
35     FFT(a,len,1);FFT(b,len,1);
36     for(int i=0;i<len;i++)a[i]*=b[i];
37     FFT(a,len,-1);
38     for(int i=0;i<=n+m;i++)cout<<(int)(a[i].real()/len+0.5)<<" ";
39 }
FFT递归版
 1 #include<iostream>
 2 #include<cstring>
 3 #include<complex>
 4 #include<cstdio>
 5 #define cp complex<double>
 6 using namespace std;
 7 const double pi=3.14159265358979;
 8 
 9 int rev[1000000];
10 void FFT(cp *a,int n,int inv)
11 {
12     int bit=0;while((1<<bit)<n)bit++;
13     for(int i=0;i<n;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(bit-1));
14     for(int i=0;i<n;i++)if(i<rev[i])swap(a[i],a[rev[i]]);
15     for(int mid=1;mid<n;mid*=2)
16     {    
17         cp temp(cos(pi/mid),inv*sin(pi/mid));
18         for(int i=0;i<n;i+=mid*2)
19         {
20             cp ome(1,0);
21             for(int j=0;j<mid;j++,ome*=temp)
22             {
23                 cp x=a[i+j],y=ome*a[i+j+mid];
24                 a[i+j]=x+y,a[i+j+mid]=x-y;
25             }
26         }
27     }
28 }
29 int n,m;
30 cp a[1000010],b[1000010];int c[1000010];
31 signed main()
32 {
33 //    freopen("1.in","r",stdin);
34 //    freopen("out.out","w",stdout);
35 
36     cin>>n>>m;double tem;
37     for(int i=0;i<=n;i++)scanf("%lf",&tem),a[i]=cp(tem,0);
38     for(int i=0;i<=m;i++)scanf("%lf",&tem),b[i]=cp(tem,0);
39     int len=n+m+1,now=1;
40     for(;;now*=2)if(now>=len){len=now;break;}
41     FFT(a,len,1);FFT(b,len,1);
42     for(int i=0;i<len;i++)a[i]*=b[i];
43     FFT(a,len,-1);
44     for(int i=0;i<=n+m;i++)cout<<(int)(a[i].real()/len+0.5)<<" ";
45 }
FFT迭代版

 

posted @ 2019-09-17 15:43  Al_Ca  阅读(134)  评论(0编辑  收藏  举报
ヾ(≧O≦)〃嗷~