[2017.12.2]FFT学习笔记

墙裂推荐两个博客:

http://blog.csdn.net/iamzky/article/details/22712347   画了图,写的很容易懂,配合《算法导论》服用更佳

http://blog.xlightgod.com/%e3%80%90uoj34%e3%80%91%e5%a4%9a%e9%a1%b9%e5%bc%8f%e4%b9%98%e6%b3%95/    XlightGod大佬的博客,写的很清楚,模板也非常棒

最后上我自己修改过的XlightGod的模板,符合自己风格

 1 #include<bits/stdc++.h>
 2 #define N 100010
 3 #define RG register
 4 #define inf 0x3f3f3f3f
 5 using namespace std;
 6 const double pi=acos(-1);
 7 typedef complex<double> C;
 8 C a[N],b[N];
 9 int L,m,n,R[N];
10 inline int gi(){
11     RG int x=0;RG char y=getchar();
12     while(y<'0'||y>'9') y=getchar();
13     while(y>='0'&&y<='9') x=x*10+y-'0',y=getchar();
14     return x;
15 }
16 inline void fft(C *x,int y){
17     for (RG int i=0;i<n;++i)
18     if(i<R[i]) 
19         swap(x[i],x[R[i]]);//交换位置,数组总要换回来吧
20     for (RG int i=1;i<n;i<<=1){//待合并区间长度
21     C wn(cos(pi/i),sin(y*pi/i)),even,odd;
22     //这里就不用再*2了,因为合并后的区间长度是i的两倍(这里的i可以理解为len/2)
23     for (RG int j=0;j<n;j+=i<<1){//起始位置
24         C w(1,0);
25         for (RG int k=0;k<i;++k,w*=wn){//第几个,类似于递归版的for(i~len/2)
26         even=x[j+k];
27         odd=w*x[j+i+k];
28         x[j+k]=even+odd;
29         x[j+i+k]=even-odd;
30         }
31     }
32     }
33 }
34 int main(){
35     freopen("34.in","r",stdin);
36     freopen("34.out","w",stdout);
37     n=gi();m=gi();
38     for (RG int i=0;i<=n;++i) a[i]=gi();
39     for (RG int i=0;i<=m;++i) b[i]=gi();
40     for (m+=n,n=1;n<=m;n<<=1) ++L;
41     for (RG int i=0;i< n;++i) R[i]=(R[i>>1]>>1)|((i&1)<<(L-1));//递推
42     fft(a,1);fft(b,1);
43     for (RG int i=0;i<=n;++i) a[i]*=b[i];
44     fft(a,-1);
45     for (RG int i=0;i<=m;++i) printf("%d ",int(a[i].real()/n+0.5));
46     return 0;
47 }
View Code

 关于FFT和卷积,这篇博客写得不错

http://blog.csdn.net/xienaoban/article/details/69486299

posted @ 2017-12-02 22:02  Super_Nick  阅读(236)  评论(0编辑  收藏  举报