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