洛谷P3803【模板】多项式乘法(FFT)
题面
题目背景
这是一道 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)); }