题目链接
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;
}