【Loj108】多項式乘法
阿新 • • 發佈:2018-11-26
n) efi lex desc sam int str sdi math
題面
Description
輸入兩個多項式,輸出這兩個多項式的乘積。
Input
第一行兩個整數 n 和 m,分別表示兩個多項式的次數。
第二行 n+1個整數,分別表示第一個多項式的 0到 n 次項前的系數。
第三行 m+1個整數,分別表示第二個多項式的 0到 m次項前的系數。
Output
輸出僅一行 n+m+1個整數,分別表示乘起來後的多項式的 0到 n+m次項前的系數。
Sample Input
1 2 1 2 1 2 1
Sample Output
1 4 5 2
Hint
\(0≤n,m≤10^5\) ,保證輸入中的系數大於等於 0且小於等於 9。
代碼如下
FFT模板
#include<iostream> #include<cstring> #include<cmath> #include<algorithm> #include<cstdio> #include<iomanip> #include<cstdlib> #include<complex> #define MAXN 0x7fffffff typedef long long LL; const int N=400005; using namespace std; inline int Getint(){register int x=0,f=1;register char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}return x*f;} typedef complex<double> Z; const double pi=M_PI; int rev[N]; void FFT(Z *a,int x,int K){ int n=(1<<x); for(int i=0;i<n;i++)if(i<rev[i])swap(a[i],a[rev[i]]); for(int i=1;i<n;i<<=1){ int tmp=i<<1; Z wn(cos(pi/i),sin(pi*K/i)); for(int j=0;j<n;j+=tmp){ Z w(1,0); for(int k=0;k<i;k++,w=w*wn){ Z x=a[j+k],y=w*a[i+j+k]; a[j+k]=x+y;a[i+j+k]=x-y; } } } if(K==-1)for(int i=0;i<n;i++)a[i]/=n; } Z a[N],b[N]; int main(){ int n=Getint(),m=Getint(); for(int i=0;i<=n;i++)a[i].real()=Getint(); for(int i=0;i<=m;i++)b[i].real()=Getint(); int x=ceil(log2(n+m+1)); for(int i=0;i<(1<<x);i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<x-1); FFT(a,x,1),FFT(b,x,1); for(int i=0;i<(1<<x);i++)a[i]*=b[i]; FFT(a,x,-1); for(int i=0;i<=n+m;i++)cout<<(int)(a[i].real()+0.5)<<' '; return 0; }
NTT模板
#include<iostream> #include<cstring> #include<cmath> #include<algorithm> #include<cstdio> #include<iomanip> #include<cstdlib> #include<complex> #define MAXN 0x7fffffff typedef long long LL; const int N=400005,mod=998244353; using namespace std; inline int Getint(){register int x=0,f=1;register char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}return x*f;} int rev[N]; int ksm(int x,int k){ int ret=1; while(k){ if(k&1)ret=1ll*ret*x%mod; x=1ll*x*x%mod,k>>=1; } return ret; } void NTT(int *a,int x,int K){ int n=(1<<x); for(int i=0;i<n;i++)if(i<rev[i])swap(a[i],a[rev[i]]); for(int i=1;i<n;i<<=1){ int tmp=i<<1,wn=ksm(3,(mod-1)/tmp); if(K==-1)wn=ksm(wn,mod-2); for(int j=0;j<n;j+=tmp){ int w=1; for(int k=0;k<i;k++,w=(LL)w*wn%mod){ int x=a[j+k],y=(LL)w*a[i+j+k]%mod; a[j+k]=(x+y)%mod;a[i+j+k]=(x-y+mod)%mod; } } } if(K==-1){ int inv=ksm(n,mod-2); for(int i=0;i<n;i++)a[i]=(LL)a[i]*inv%mod; } } int a[N],b[N]; int main(){ int n=Getint(),m=Getint(); for(int i=0;i<=n;i++)a[i]=Getint(); for(int i=0;i<=m;i++)b[i]=Getint(); int x=ceil(log2(n+m+1)); for(int i=0;i<(1<<x);i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<x-1); NTT(a,x,1),NTT(b,x,1); for(int i=0;i<(1<<x);i++)a[i]=(LL)a[i]*b[i]%mod; NTT(a,x,-1); for(int i=0;i<=n+m;i++)cout<<a[i]<<' '; return 0; }
【Loj108】多項式乘法