[BZOJ2179]FFT快速傅立叶

来源:互联网 发布:苹果笔记本windows系统 编辑:程序博客网 时间:2024/04/30 23:46

原题地址

为什么自己写的FFT辣么慢…

值得注意的地方:
1.蝴蝶操作那里把公用子表达式(《算导》里看到的名词,感觉好高大上…)存在tmp变量中可以让程序变快一点(本题快了差不多一秒).
2.STLcomplex类型使用时要注意不同类型变量运算时要有一些类型转换,具体看代码(其实你看哪里CE就行了…).

AC code:

#include <cstdio>#include <complex>#include <cmath>using namespace std;typedef double llf;typedef complex<llf> comp;const int N=1000010;const llf PI=acos(-1);int  n,l,w;int  ans[N];comp a[N],b[N],c[N],ya[N],yb[N],yc[N],t[N];int rev(int x){    int y=0;    int t[1<<6];    for(int i=1;i<=w;i++,x>>=1) t[i]=x&1;    for(int i=1;i<=w;i++) y=(y<<1)^t[i];    return y;}void FFT(comp y[],comp a[],bool type){    for(int i=0;i<l;i++) y[rev(i)]=a[i];    for(int i=1;i<=w;i++){        for(int j=0;j<l;j+=(1<<i)){            int  x=1<<(i-1);            comp tmp,o(1.0,0.0),omg(cos(2*PI/(1<<i)),sin(2*PI/(1<<i)));            if(type) omg=1.0/omg;            for(int k=0;k<x;k++,o*=omg){                tmp=o*y[j+k+x];                t[j+k]=y[j+k]+tmp;                t[j+k+x]=y[j+k]-tmp;            }        }        for(int j=0;j<l;j++) y[j]=t[j];    }    if(type) for(int i=0;i<l;i++) y[i]=y[i]/(llf)l;}int main(){    scanf("%d\n",&n);    for(int i=n-1;i>=0;i--){        char t;        scanf("%c",&t);        a[i].real()=t-'0';    }    scanf("\n");    for(int i=n-1;i>=0;i--){        char t;        scanf("%c",&t);        b[i].real()=t-'0';    }    l=1<<((int)log2(n)+2);w=(int)log2(l);    FFT(ya,a,0);FFT(yb,b,0);    for(int i=0;i<l;i++) yc[i]=ya[i]*yb[i];    FFT(c,yc,1);    for(int i=0;i<l;i++) ans[i]=(int)(c[i].real()+0.1);    for(int i=0;i<l;i++){        ans[i+1]+=ans[i]/10;        ans[i]%=10;    }    if(ans[(n<<1)-1]) printf("%d",ans[(n<<1)-1]);    for(int i=(n<<1)-2;i>=0;i--) printf("%d",ans[i]);    return 0;}
0 0
原创粉丝点击