墙裂推荐两个博客:
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 }
关于FFT和卷积,这篇博客写得不错
http://blog.csdn.net/xienaoban/article/details/69486299