FFT(快速傅里叶变换)


题目链接

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

3122. 多项式乘法

题目描述

给定一个 \(n\) 次多项式 \(F(x)=a_0+a_1x+a_2x_2+…+a_nx_n\)

以及一个 \(m\) 次多项式 \(G(x)=b_0+b_1x+b_2x_2+…+b_mx_m\)

已知 \(H(x)=F(x)⋅G(x)=c_0+c_1x+c_2x_2+…+c_{n+m}x_{n+m}\)

请你计算并输出 \(c_0,c_1,…,c_{n+m}\)

输入格式

第一行包含两个整数 \(n,m\)

第二行包含 \(n+1\) 个整数 \(a_0,a_1,…,a_n\)

第三行包含 \(m+1\) 个整数 \(b_0,b_1,…,b_m\)

输出格式

共一行,依次输出 \(c_0,c_1,…,c_{n+m}\)

数据范围

\(1≤n,m≤10^5\),
\(0≤a_i,b_i≤9\)

输入样例:

1 2
1 3
2 2 1

输出样例:

2 8 7 3
  • 时间复杂度:\(O(nlogn)\)

代码

#include<cmath>
#include<cstdio>
using namespace std;
const int N=3e5+10;
const double PI=acos(-1);
int n,m;
struct Complex
{
    double x,y;
    Complex operator+ (const Complex& t)const
    {
        return {x+t.x,y+t.y};
    }
    Complex operator- (const Complex& t)const
    {
        return {x-t.x,y-t.y};
    }
    Complex operator* (const Complex& t)const
    {
        return {x*t.x-y*t.y,x*t.y+y*t.x};
    }
}a[N],b[N];
int rev[N],bit,tot;
void fft(Complex a[],int inv)
{
    for(int i=0;i<tot;i++)
        if(i<rev[i])
            swap(a[i],a[rev[i]]);
    for(int mid=1;mid<tot;mid<<=1)
    {
        auto w1=Complex({cos(PI/mid),inv*sin(PI/mid)});
        for(int i=0;i<tot;i+=mid*2)
        {
            auto wk=Complex({1,0});
            for(int j=0;j<mid;j++,wk=wk*w1)
            {
                auto x=a[i+j],y=wk*a[i+j+mid];
                a[i+j]=x+y,a[i+j+mid]=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((1<<bit)<n+m+1)bit++;
    tot=1<<bit;
    for(int i=0;i<tot;i++)
        rev[i]=(rev[i>>1]>>1)|((i&1)<<(bit-1));
    fft(a,1),fft(b,1);
    for(int i=0;i<tot;i++)a[i]=a[i]*b[i];
    fft(a,-1);
    for(int i=0;i<=n+m;i++)
        printf("%d ",(int)(a[i].x/tot+0.5));
    return 0;
}


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM