【bzoj 2194】快速傅立叶之二(FFT)

来源:互联网 发布:棍刀淘宝 编辑:程序博客网 时间:2024/05/18 02:10

传送门biu~
FFT没有完全搞懂,扒了一份LZJ209学长的代码留着以后慢慢理解。

#include<bits/stdc++.h>using namespace std;const double DFT=2.0,IDFT=-2.0,pi=acos(-1);double trans_form;int len,pos[300005];struct data{    double a,b;    data()  {}    data(double _,double __){a=_;b=__;}    data operator +(const data&r)const{return data(a+r.a,b+r.b);}    data operator -(const data&r)const{return data(a-r.a,b-r.b);}    data operator *(const data&r)const{return data(a*r.a-b*r.b,a*r.b+b*r.a);}}a[300005],b[300005],c[300005];void init(){    for(int i=0;i<len;++i){        pos[i]=pos[i>>1]>>1;        if(i&1) pos[i]|=(len>>1);    }}void fft(data x[]){    for(int i=0;i<len;++i){        if(i<pos[i])    swap(x[i],x[pos[i]]);    }    for(int i=2;i<=len;i<<=1){        int step=i>>1;        data wm(cos(2*pi/i),sin(trans_form*pi/i));        for(int j=0;j<len;j+=i){            int limit=j+step;            data ww(1,0);            for(int k=j;k<limit;++k){                data a=x[k];                data b=x[k+step]*ww;                ww=ww*wm;                x[k]=a+b;                x[k+step]=a-b;            }        }    }    if(trans_form==IDFT)    for(int i=0;i<len;++i)  x[i].a/=len;}int main(){    int n;    scanf("%d",&n);    len=1;    while(len<(n<<1))   len<<=1;    init();    for(int i=1;i<=n;++i){        int x,y;        scanf("%d%d",&x,&y);        a[n-i].a=x;        b[i-1].a=y;    }    trans_form=DFT;    fft(a);    fft(b);    for(int i=0;i<len;++i)  c[i]=a[i]*b[i];    trans_form=IDFT;    fft(c);    int top=0;    for(int i=n-1;i>=0;--i) printf("%d\n",(int)(c[i].a+0.5));    return 0;}
原创粉丝点击