【模板】FFT

来源:互联网 发布:守望先锋数据 编辑:程序博客网 时间:2024/06/02 03:02

不是我写的。作者见这里:传送门

#include <cmath>#include <queue>#include <cstdio>#include <iomanip>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>#define N 400000#define ll long long#define inf 1000000000using namespace std;inline int read() {     int x=0,f=1;char ch=getchar();     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}     return x*f; }struct cp{    double x,y;    cp(double X=0,double Y=0)    {        x=X,y=Y;    }}a[N],b[N],c[N];cp operator +(cp a,cp b){return cp(a.x+b.x,a.y+b.y);}cp operator -(cp a,cp b){return cp(a.x-b.x,a.y-b.y);}cp operator *(cp a,cp b){return cp(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);}int r[N],L;int n,m,lim;void fft(cp *a,int n,int flag){    for(int i=0;i<n;i++)     if(r[i]>i)swap(a[i],a[r[i]]);    for(int i=1;i<n;i<<=1)     {        cp w_n(cos(M_PI/i),flag*sin(M_PI/i));        for(int j=0;j<n;j+=i<<1)         {            cp w(1,0);            for(int k=0;k<i;k++)             {                cp x=a[j+k],y=w*a[j+k+i];                a[j+k]=x+y,a[j+k+i]=x-y;                w=w*w_n;            }        }    }}int main(){    n=read(),m=read();    for(int i=0;i<=n;i++)a[i].x=read();    for(int i=0;i<=m;i++)b[i].x=read();    m=n+m;    for(lim=1;lim<=m;lim<<=1)L++;    for(int i=0;i<=lim;i++)    r[i]=((r[i>>1]>>1)|(i&1)<<(L-1));    fft(a,lim,1),fft(b,lim,1);    for(int i=0;i<lim;i++)    c[i]=a[i]*b[i];    fft(c,lim,-1);    for(int i=0;i<=m;i++)    printf("%d ",(int)(c[i].x/lim+0.1));}
原创粉丝点击