FFT一周目开坑!

先来一段非递归!

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N ((1<<18)+3)
 4 const double eps=0.5,pi=acos(-1);
 5 struct vec{
 6     double r,i;
 7     vec operator +(const vec& w){return (vec){r+w.r,i+w.i};}
 8     vec operator -(const vec& w){return (vec){r-w.r,i-w.i};}
 9     vec operator *(const vec& w){return (vec){r*w.r-i*w.i,i*w.r+r*w.i};}
10 }a[N],b[N];
11 int n,m,len,rev[N],t;
12 bool che[N];
13 int read(){
14     int f=1,a=getchar(),tmp=0;
15     while(a<'0' || a>'9') {if(a=='-') f=-1; a=getchar();}
16     while(a>='0'&& a<='9') tmp=tmp*10+a-'0',a=getchar();
17     return tmp*=f;
18 }
19 void fft(vec *x,int t){
20     memset(che,0,sizeof(che));
21     for(int i=0;i<len;i++) if(!che[i]) swap(x[i],x[rev[i]]),che[rev[i]]=1;
22     for(int lnow=2;lnow<=len;lnow<<=1){   //从最底层开始往上推,一开始每一小坨只有2个,慢慢往上到最后达到len 
23         vec w0=(vec){cos(t*2*pi/lnow),sin(t*2*pi/lnow)},w,t1,t2;
24         for(int i=0;i<len;i+=lnow){ //每一坨
25             vec w=(vec){1,0};
26             for(int j=0;j<lnow/2;j++,w=w*w0){ 
27                 t1=x[i+j]; t2=w*x[i+j+lnow/2];
28                 x[i+j]=t1+t2; x[i+j+lnow/2]=t1-t2;
29             }
30         }
31     }
32 }
33 int main(){
34     n=read(); m=read();
35     for(len=1;len<(n+m+1);len<<=1,t++); t--;
36     for(int i=1;i<=len;i++) rev[i]=(rev[i>>1]>>1)|(i&1?(1<<t):0); //二进制反转,注意之前的t-- 
37     for(int i=0;i<=n;i++) a[i].r=read();
38     for(int i=0;i<=m;i++) b[i].r=read();
39     fft(a,1); fft(b,1);
40     for(int i=0;i<=len;i++) a[i]=a[i]*b[i];
41     fft(a,-1);
42     for(int i=0;i<=n+m;i++) printf("%d ",(int)(a[i].r/len+eps));
43     return 0;
44 }
原文地址:https://www.cnblogs.com/enigma-aw/p/5957550.html