2194: 快速傅立叶之二 FFT

来源:互联网 发布:流畅的python 编辑:程序博客网 时间:2024/05/17 08:25

继续模板

#include<iostream>#include<cstdio>#include<cmath>#include<cstring>using namespace std;const int N=400005;const double PI=acos(-1);int n,rev[N];struct C{    double real,i;    C(double a=0,double b=0) {real=a; i=b;}    C operator+(C x) {return C(real+x.real,i+x.i);}    C operator-(C x) {return C(real-x.real,i-x.i);}    C operator*(C x) {return C(real*x.real-i*x.i,real*x.i+x.real*i);}}a[N],b[N];inline void FFT(C x[],int T){    for (int i=0;i<n;i++)         if (rev[i]<i) swap(x[i],x[rev[i]]);    for (int i=2;i<=n;i<<=1)    {        C wn(cos(2*PI/i),T*sin(2*PI/i));        for (int j=0;j<n;j+=i)        {            C t,tmp,w(1,0);            for (int k=0;k<(i>>1);k++)            {                tmp=x[j+k];                t=w*x[j+k+(i>>1)];                x[j+k]=tmp+t;                x[j+k+(i>>1)]=tmp-t;                w=w*wn;            }        }    }}int main(){    scanf("%d",&n);    for (int i=0;i<n;i++)         scanf("%lf%lf",&a[i].real,&b[n-i-1].real);    int tmp=n,m=n<<1|1;    n=1;    while (n<=m) n<<=1;    for (int i=0;i<n;i++)        rev[i]=(rev[i>>1]>>1)|((i&1)?n>>1:0);    FFT(a,1); FFT(b,1);    for (int i=0;i<n;i++)         a[i]=a[i]*b[i];    FFT(a,-1);    for (int i=0;i<tmp;i++)        printf("%d\n",(int)(a[i+tmp-1].real/n+0.5));    return 0;}
0 0
原创粉丝点击