uoj#34. 多项式乘法
Posted wfj_2048
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了uoj#34. 多项式乘法相关的知识,希望对你有一定的参考价值。
题面:http://uoj.ac/problem/34
正解:$FFT$/$NTT$。
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学长博客。
FFT:
1 //It is made by wfj_2048~ 2 #include <algorithm> 3 #include <iostream> 4 #include <complex> 5 #include <cstring> 6 #include <cstdlib> 7 #include <cstdio> 8 #include <vector> 9 #include <cmath> 10 #include <queue> 11 #include <stack> 12 #include <map> 13 #include <set> 14 #define inf (1<<30) 15 #define pi acos(-1) 16 #define N (600010) 17 #define il inline 18 #define RG register 19 #define ll long long 20 #define C complex<double> 21 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout) 22 23 using namespace std; 24 25 int rev[N],n,m,lg; 26 char sa[N],sb[N]; 27 C a[N],b[N]; 28 29 il int gi(){ 30 RG int x=0,q=1; RG char ch=getchar(); 31 while ((ch<‘0‘ || ch>‘9‘) && ch!=‘-‘) ch=getchar(); 32 if (ch==‘-‘) q=-1,ch=getchar(); 33 while (ch>=‘0‘ && ch<=‘9‘) x=x*10+ch-48,ch=getchar(); 34 return q*x; 35 } 36 37 il void fft(C *a,int n,int f){ 38 for (RG int i=0;i<n;++i) if (i<rev[i]) swap(a[i],a[rev[i]]); 39 for (RG int i=1;i<n;i<<=1){ 40 C wn(cos(pi/i),sin(f*pi/i)),x,y; 41 for (RG int j=0;j<n;j+=(i<<1)){ 42 C w(1,0); 43 for (RG int k=0;k<i;++k,w*=wn){ 44 x=a[j+k],y=w*a[j+k+i]; 45 a[j+k]=x+y,a[j+k+i]=x-y; 46 } 47 } 48 } 49 } 50 51 il void work(){ 52 n=gi()+1,m=gi()+1; for (RG int i=0;i<n;++i) a[i]=gi(); 53 for (RG int i=0;i<m;++i) b[i]=gi(); m+=n; for (n=1;n<=m;n<<=1) lg++; 54 for (RG int i=1;i<=n;++i) rev[i]=(rev[i>>1]>>1)|((i&1)<<(lg-1)); 55 fft(a,n,1),fft(b,n,1); for (RG int i=0;i<n;++i) a[i]*=b[i]; fft(a,n,-1); 56 for (RG int i=0;i<m-1;++i) printf("%d ",(int)(a[i].real()/n+0.5)); return; 57 } 58 59 int main(){ 60 File("fft"); 61 work(); 62 return 0; 63 }
NTT:
1 //It is made by wfj_2048~ 2 #include <algorithm> 3 #include <iostream> 4 #include <complex> 5 #include <cstring> 6 #include <cstdlib> 7 #include <cstdio> 8 #include <vector> 9 #include <cmath> 10 #include <queue> 11 #include <stack> 12 #include <map> 13 #include <set> 14 #define rhl (998244353) 15 #define inf (1<<30) 16 #define N (300010) 17 #define G (3) 18 #define il inline 19 #define RG register 20 #define ll long long 21 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout) 22 23 using namespace std; 24 25 int rev[N],n,m,lg; 26 ll a[N],b[N]; 27 28 il int gi(){ 29 RG int x=0,q=1; RG char ch=getchar(); 30 while ((ch<‘0‘ || ch>‘9‘) && ch!=‘-‘) ch=getchar(); 31 if (ch==‘-‘) q=-1,ch=getchar(); 32 while (ch>=‘0‘ && ch<=‘9‘) x=x*10+ch-48,ch=getchar(); 33 return q*x; 34 } 35 36 il ll qpow(RG ll a,RG ll b){ 37 RG ll ans=1; 38 while (b){ 39 if (b&1) (ans*=a)%=rhl; 40 (a*=a)%=rhl,b>>=1; 41 } 42 return ans; 43 } 44 45 il void NTT(ll *a,RG int n,RG int f){ 46 for (RG int i=0;i<n;++i) if (i<rev[i]) swap(a[i],a[rev[i]]); 47 for (RG int i=1;i<n;i<<=1){ 48 RG ll gn=qpow(G,(rhl-1)/(i<<1)),x,y; 49 for (RG int j=0;j<n;j+=(i<<1)){ 50 RG ll g=1; 51 for (RG int k=0;k<i;++k,(g*=gn)%=rhl){ 52 x=a[j+k],y=g*a[j+k+i]%rhl; 53 a[j+k]=(x+y)%rhl,a[j+k+i]=(x-y+rhl)%rhl; 54 } 55 } 56 } 57 if (f==1) return; reverse(a+1,a+n); RG ll inv=qpow(n,rhl-2); 58 for (RG int i=0;i<n;++i) (a[i]*=inv)%=rhl; return; 59 } 60 61 il void work(){ 62 n=gi()+1,m=gi()+1; 63 for (RG int i=0;i<n;++i) a[i]=gi(); 64 for (RG int i=0;i<m;++i) b[i]=gi(); 65 m+=n; for (n=1;n<=m;n<<=1) lg++; 66 for (RG int i=0;i<n;++i) rev[i]=(rev[i>>1]>>1)|((i&1)<<(lg-1)); 67 NTT(a,n,1),NTT(b,n,1); for (RG int i=0;i<n;++i) (a[i]*=b[i])%=rhl; 68 NTT(a,n,-1); for (RG int i=0;i<m-1;++i) printf("%lld ",a[i]); return; 69 } 70 71 int main(){ 72 File("NTT"); 73 work(); 74 return 0; 75 }
以上是关于uoj#34. 多项式乘法的主要内容,如果未能解决你的问题,请参考以下文章