题目背景
这是一道FFT模板题
注意:虽然本题开到3s,但是建议程序在1s内可以跑完,本题需要一定程度的常数优化。
题目描述
给定一个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)的系数。
输入输出样例
说明
保证输入中的系数大于等于 0 且小于等于9。
对于100%的数据: n,m≤106 n, m leq {10}^6 n,m≤106, 共计20个数据点,2s。
数据有一定梯度。
空间限制:256MB
多项式卷积模板
1 #include"bits/stdc++.h" 2 #define sd(x) scanf("%lf",&(x)); 3 #define sld(x) scanf("%lld",&(x)); 4 using namespace std; 5 6 const int maxn = 1e7+10; 7 const double Pi = acos(-1.0); 8 struct cp 9 { 10 double x,y; 11 cp (double xx=0,double yy=0) 12 {x=xx,y=yy;} 13 }a[maxn],b[maxn]; 14 cp operator + (cp a,cp b){ return cp(a.x+b.x , a.y+b.y);} 15 cp operator - (cp a,cp b){ return cp(a.x-b.x , a.y-b.y);} 16 cp operator * (cp a,cp b){ return cp(a.x*b.x-a.y*b.y , a.x*b.y+a.y*b.x);}//不懂的看复数的运算那部分 17 18 int n,m; 19 int l,r[maxn]; 20 int limit = 1; 21 22 23 inline void ffft(cp *a,int ff) 24 { 25 for(int i=0;i<limit;i++) 26 if(i<r[i])swap(a[i],a[r[i]]); 27 for(int mid=1;mid<limit;mid<<=1) 28 { 29 cp wn(cos(Pi/mid) , ff*sin(Pi/mid)); 30 for(int R=mid<<1,j=0;j<limit;j+=R) 31 { 32 cp w(1,0); 33 for(int k=0;k<mid;k++,w=w*wn) 34 { 35 cp x=a[j+k],y=w*a[j+mid+k]; 36 a[j+k]=x+y; 37 a[j+mid+k]=x-y; 38 } 39 } 40 41 } 42 43 } 44 45 int main() 46 { 47 cin>>n>>m; 48 for(int i=0;i<=n;i++)sd(a[i].x); 49 for(int i=0;i<=m;i++)sd(b[i].x); 50 51 52 while(limit<=n+m)limit<<=1,l++; 53 for(int i=0;i<limit;i++) 54 r[i]=(r[i>>1]>>1)|( (i&1)<<(l-1)); 55 56 ffft(a,1); 57 ffft(b,1); 58 59 for(int i=0;i<=limit;i++)a[i]=a[i]*b[i]; 60 ffft(a,-1); 61 for(int i=0;i<=n+m;i++) 62 printf("%d ",(int)(a[i].x/limit + 0.5)); 63 return 0; 64 65 66 67 68 }