FFT模板(迭代/递归)

来源:互联网 发布:php编辑器 编辑:程序博客网 时间:2024/06/15 13:43
#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>#include<complex>using namespace std;#define pi acos(-1.0)const int maxn=300010;typedef complex<double>C;C a[maxn],b[maxn];void fft(C *x,int n,int type){    if(n==1) return;    C l[n>>1],r[n>>1];    for(int i=0;i<n;i+=2) l[i>>1]=x[i],r[i>>1]=x[i+1];    fft(l,n>>1,type);fft(r,n>>1,type);    C wn(cos(2*pi/n),sin(type*2*pi/n)),w(1,0);    for(int i=0;i<(n>>1);i++,w*=wn)        x[i]=l[i]+w*r[i],x[i+(n>>1)]=l[i]-w*r[i];}int rev[maxn];int n,m;void init(){    for(int i=0;i<n;i++) rev[i]=(rev[i>>1]>>1)|((i&1)?(n>>1):0);}void FFT(C *x,int n,int type){    for(int i=1;i<n;i++) if(i<rev[i]) swap(x[rev[i]],x[i]);    for(int k=2;k<=n;k<<=1){        C wn(cos(2*pi/k),sin(type*2*pi/k));        for(int i=0;i<n;i+=k){            C w(1,0);            for(int j=0;j<(k>>1);j++){                C l=x[i+j],r=x[i+j+(k>>1)];                x[i+j]=l+w*r;                x[i+j+(k>>1)]=l-w*r;                w*=wn;            }        }    }}int main(){    scanf("%d%d",&n,&m);    for(int i=0;i<=n;i++) scanf("%lf",&a[i].real());    for(int i=0;i<=m;i++) scanf("%lf",&b[i].real());    m+=n;    for(n=1;n<=m;n<<=1);    init();    FFT(a,n,1);FFT(b,n,1);    for(int i=0;i<=n;i++) a[i]*=b[i];    FFT(a,n,-1);    for(int i=0;i<=m;i++) printf("%d ",(int)(a[i].real()/n+0.5));    return 0;}

^_^

0 0
原创粉丝点击