FFT(模板)

来源:互联网 发布:anello淘宝上有正品吗 编辑:程序博客网 时间:2024/06/01 10:13

优美

这里写代码片#include<cstdio>#include<cstring>#include<iostream>#include<cmath>using namespace std;const int N=301000;const double pi=acos(-1.0);struct node{    double x,y;    node (double xx=0,double yy=0)    {        x=xx;y=yy;    }};node a[N],b[N],omega[N],a_omega[N];int n,m,fn;node operator +(const node &a,const node &b){return node(a.x+b.x,a.y+b.y);}node operator -(const node &a,const node &b){return node(a.x-b.x,a.y-b.y);}node operator *(const node &a,const node &b){return node (a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);}void init(int n){    for (int i=0;i<n;i++)    {        omega[i]=node(cos(2.0*i*pi/n),sin(2.0*i*pi/n));        a_omega[i]=node(cos(2.0*i*pi/n),-sin(2.0*i*pi/n));    }} void FFT(int n,node *a,node *w){    int i,j=0,k;    for (i=0;i<n;i++)    {        if (i>j) swap(a[i],a[j]);        for (int l=n>>1;(j^=l)<l;l>>=1);   ///    }    for (i=2;i<=n;i<<=1)    {        int m=i>>1;        for (j=0;j<n;j+=i)            for (k=0;k<m;k++)            {                node z=a[j+k+m]*w[n/i*k];  ///                a[j+m+k]=a[j+k]-z;                a[j+k]=a[j+k]+z;            }    }}int main(){    scanf("%d%d",&n,&m);    for (int i=0;i<=n;i++) scanf("%lf",&a[i].x);    for (int i=0;i<=m;i++) scanf("%lf",&b[i].x);    fn=1;    while (fn<=n+m) fn<<=1;    init(fn);  //处理主n次方根     FFT(fn,a,omega);   //转成点值表达     FFT(fn,b,omega);    for (int i=0;i<=fn;i++)        a[i]=a[i]*b[i];    FFT(fn,a,a_omega);  //转成系数表达    for (int i=0;i<=n+m;i++) printf("%d ",(int)(a[i].x/fn+0.5));     return 0; }
原创粉丝点击