【模板】多项式乘法(FFT)

【模板】多项式乘法(FFT)(luogu)

洛谷题解传送

这是一道多项式乘法模板题 n<=10^6

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#define db double
using namespace std;
const int N=3e6+10;
const db Pi=acos(-1.0);
struct cp
{
    db x,y;
    cp(db xx=0,db yy=0)
    {
        x=xx,y=yy;
    }
}a[N],b[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 n,m,rev[N],limit=1,l;
void FFT(cp *a,int inv)
{
    for(int i=0;i<limit;i++) 
        if(i<rev[i]) swap(a[i],a[rev[i]]);
    for(int mid=1;mid<limit;mid<<=1)
    {
        cp wn(cos(Pi/mid),inv*sin(Pi/mid));
        for(int R=mid<<1,j=0;j<limit;j+=R)
        {
            cp w(1,0);
            for(int k=0;k<mid;k++,w=w*wn)
            {
                cp x=a[j+k],y=w*a[j+mid+k];
                a[j+k]=x+y,a[j+mid+k]=x-y;
            }
        }
    }
}
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);
    while(limit<=n+m) limit<<=1,l++;
    for(int i=0;i<limit;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(l-1));
    FFT(a,1),FFT(b,1);
    for(int i=0;i<=limit;i++) a[i]=a[i]*b[i];
    FFT(a,-1);
    for(int i=0;i<=n+m;i++) printf("%d ",(int)(a[i].x/limit+0.5));
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/hsez-cyx/p/12382043.html
今日推荐