题面
题目背景
这是一道 FFT 模板题
题目描述
给定一个$n$次多项式$F(x)$,和一个$m$次多项式$G(x)$。
请求出$F(x)$和$G(x)$的卷积。
输入格式
第一行 2 个正整数$n,m$。
接下来一行$n+1$个数字,从低到高表示$F(x)$的系数。
接下来一行$m+1$个数字,从低到高表示$G(x)$的系数。
输出格式
一行$n+m+1$个数字,从低到高表示$F(x)*G(x)$的系数。
输入输出样例
输入 #1
1 2
1 2
1 2 1
输出 #1
1 4 5 2
说明/提示
保证输入中的系数大于等于 0 且小于等于 9。
对于100%的数据:$n,m<=10^{6}$
题意
就是一道FFT模板,给出一个n次多项式系数,一个m次多项式系数,求它们乘积的多项式每一项的系数。
题解
模板,不解释
#include<cmath>
using namespace std;
const int N=1e7+5;
const double PI=acos(-1.0);
int lena,lenb,n=1,lim,r[N];
struct cp{
double x,y;
cp(double _x=0,double _y=0){
x=_x;y=_y;
}
cp operator*(cp b){
return cp(x*b.x-y*b.y,x*b.y+y*b.x);
}
cp operator+(cp b){
return cp(x+b.x,y+b.y);
}
cp operator-(cp b){
return cp(x-b.x,y-b.y);
}
}a[N],b[N];
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
void FFT(cp *A,int tp){
for(int i=0;i<n;i++)if(i<r[i])swap(A[i],A[r[i]]);
for(int i=1;i<n;i<<=1){
cp W(cos(PI/i),tp*sin(PI/i));
for(int j=i<<1,k=0;k<n;k+=j){
cp w(1,0);
for(int l=0;l<i;l++,w=w*W){
cp x=A[k+l],y=w*A[k+i+l];//替代buf
A[k+l]=x+y;
A[k+i+l]=x-y;
}
}
}
}
int main(){
lena=read();lenb=read();
while(n<=lena+lenb)n<<=1,lim++;
for(int i=0;i<=lena;i++)a[i].x=read();
for(int i=0;i<=lenb;i++)b[i].x=read();
for(int i=0;i<n;i++)r[i]=(r[i>>1]>>1)|((i&1)<<(lim-1));
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<=lena+lenb;i++)printf("%d ",(int)(a[i].x/n+0.5));
}