FFT 模板 多项式乘法

#include <bits/stdc++.h>
#define cl(a) memset(a,0,sizeof(a))
using namespace std;
const int maxn = 400005;
const double pi = acos(-1.0);
struct Complex
{
    double x,y;
    Complex(double _x=0,double _y=0)
    {
        x=_x;
        y=_y;
    }
    Complex operator +(const Complex &b)const
    {
        return Complex(x+b.x,y+b.y);
    }
    Complex operator -(const Complex &b)const
    {
        return Complex(x-b.x,y-b.y);
    }
    Complex operator *(const Complex &b)const
    {
        return Complex(x*b.x-y*b.y,x*b.y+y*b.x);
    }
} a[maxn],b[maxn];
int S,T,n,m,L,R[maxn],ans[maxn];
long long F[maxn];
double f[maxn],g[maxn];
void FFT(Complex a[],int opt)
{
    for(int i=0;i<n;i++) if(i<R[i]) swap(a[i],a[R[i]]);
    for(int k=1;k<n;k<<=1)
    {
        Complex wn = Complex( cos(pi/k),opt*sin(pi/k) );
        for(int i=0;i<n;i+=(k<<1))
        {
            Complex w = Complex(1,0);
            for(int j=0;j<k;++j,w=w*wn)
            {
                Complex x = a[i+j], y = w*a[i+j+k];
                a[i+j] = x+y;
                a[i+j+k] =x-y;

            }
        }
    }
}
void calc(int opt)
{
    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<=n;i++)
    {
        F[i] = (long long)(a[i].x/n+0.5)*opt;
    }
}
int main()
{
    scanf("%d%d",&S,&T);
    for(int i=0;i<=S;i++)
    {
        scanf("%lf",&f[i]);
    }
    for(int i=0;i<=T;i++)
    {
        scanf("%lf",&g[i]);
    }
    m = S+T;
    for(n =1;n <=m;n<<=1) ++L;
    for(int i=0;i<n;i++)
    {
        R[i] = (R[i>>1]>>1)|((i&1)<<(L-1));
    }
    for(int i=0;i<=n;i++)
    {
        a[i] = Complex(1.0*f[i],0.0);
        b[i] = Complex(1.0*g[i],0.0);
    }
    calc(1);

    for(int i=0;i<=S+T;i++)
    {
        printf("%lld ",F[i]);
    }
    return 0;
}
全部评论

相关推荐

评论
点赞
收藏
分享
牛客网
牛客企业服务