这是一道模板题。
给你两个多项式,请输出乘起来后的多项式。
第一行两个整数 nn 和 mm,分别表示两个多项式的次数。
第二行 n+1n+1 个整数,分别表示第一个多项式的 00 到 nn 次项前的系数。
第三行 m+1m+1 个整数,分别表示第一个多项式的 00 到 mm 次项前的系数。
一行 n+m+1n+m+1 个整数,分别表示乘起来后的多项式的 00 到 n+mn+m 次项前的系数。
1 2 1 2 1 2 1
1 4 5 2
(1+2x)?(1+2x+x2)=1+4x+5x2+2x3(1+2x)?(1+2x+x2)=1+4x+5x2+2x3。
0≤n,m≤1050≤n,m≤105,保证输入中的系数大于等于 00 且小于等于 99。
时间限制:1s
空间限制:256MB
正解:FFT板子题。
http://blog.xlightgod.com/%E3%80%90uoj34%E3%80%91%E5%A4%9A%E9%A1%B9%E5%BC%8F%E4%B9%98%E6%B3%95/
详见xlightgod学长博客。
//It is made by wfj_2048~ #include <algorithm> #include <iostream> #include <complex> #include <cstring> #include <cstdlib> #include <cstdio> #include <vector> #include <cmath> #include <queue> #include <stack> #include <map> #include <set> #define inf (1<<30) #define pi acos(-1) #define N (600010) #define il inline #define RG register #define ll long long #define C complex<double> #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout) using namespace std; int rev[N],n,m,lg; char sa[N],sb[N]; C a[N],b[N]; il int gi(){ RG int x=0,q=1; RG char ch=getchar(); while ((ch<‘0‘ || ch>‘9‘) && ch!=‘-‘) ch=getchar(); if (ch==‘-‘) q=-1,ch=getchar(); while (ch>=‘0‘ && ch<=‘9‘) x=x*10+ch-48,ch=getchar(); return q*x; } il void fft(C *a,int n,int f){ for (RG int i=0;i<n;++i) if (i<rev[i]) swap(a[i],a[rev[i]]); for (RG int i=1;i<n;i<<=1){ C wn(cos(pi/i),sin(f*pi/i)),x,y; for (RG int j=0;j<n;j+=(i<<1)){ C w(1,0); for (RG int k=0;k<i;++k,w*=wn){ x=a[j+k],y=w*a[j+k+i]; a[j+k]=x+y,a[j+k+i]=x-y; } } } } il void work(){ n=gi()+1,m=gi()+1; for (RG int i=0;i<n;++i) a[i]=gi(); for (RG int i=0;i<m;++i) b[i]=gi(); m+=n; for (n=1;n<=m;n<<=1) lg++; for (RG int i=1;i<=n;++i) rev[i]=(rev[i>>1]>>1)|((i&1)<<(lg-1)); fft(a,n,1),fft(b,n,1); for (RG int i=0;i<n;++i) a[i]*=b[i]; fft(a,n,-1); for (RG int i=0;i<m-1;++i) printf("%d ",(int)(a[i].real()/n+0.5)); return; } int main(){ File("fft"); work(); return 0; }
原文:http://www.cnblogs.com/wfj2048/p/6420629.html