https://www.luogu.org/problem/show?pid=3803
题目背景
这是一道模版题
题目描述
给定一个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。
总共14组测试数据。
对于第1-4组数据:n<=5000,m<=5000,20pts,0.5s。
对于第5-10组数据:n<=300000,m<=300000,60pts,1s。
对于第11-14组数据:n<=1000000,m<=1000000,20pts,2s。
数据有一定梯度。
空间限制:256MB
#include<cstdio> #include<cmath> #include<complex> using namespace std; #define N 2600001 using namespace std; const double pi=acos(-1); typedef complex<double> E; int n,m,l,r[N]; E a[N],b[N]; int read() { int x=0; char c=getchar(); while(c<'0'||c>'9') c=getchar(); while(c>='0'&&c<='9') { x=x*10+c-'0'; c=getchar(); } return x; } void fft(E *a,int f) { 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) { E wn(cos(pi/i),f*sin(pi/i)); for(int p=i<<1,j=0;j<n;j+=p) { E w(1,0); for(int k=0;k<i;k++,w*=wn) { E x=a[j+k],y=w*a[j+k+i]; a[j+k]=x+y; a[j+k+i]=x-y; } } } } int main() { n=read(); m=read(); for(int i=0;i<=n;i++) a[i]=read(); for(int i=0;i<=m;i++) b[i]=read(); m+=n; for(n=1;n<=m;n<<=1) l++; for(int i=0;i<n;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(l-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<=m;i++) printf("%d ",(int)(a[i].real()/n+0.5)); }