多项式全家桶
多项式乘法:
然而蒟蒻的我并不会证明
$FFT$:
1 struct cp{ 2 dd x,y; 3 friend cp operator + (const cp &s1,const cp &s2){ return (cp){s1.x+s2.x,s1.y+s2.y}; } 4 friend cp operator - (const cp &s1,const cp &s2){ return (cp){s1.x-s2.x,s1.y-s2.y}; } 5 friend cp operator * (const cp &s1,const cp &s2){ return (cp){s1.x*s2.x-s1.y*s2.y,s1.y*s2.x+s1.x*s2.y}; } 6 }A[N1],B[N1],C[N1]; 7 8 int r[N1]; 9 void FFT(cp *s,int len,int type) 10 { 11 int i,j,k; 12 for(i=0;i<len;i++) if(i<r[i]) swap(s[i],s[r[i]]); 13 for(k=2;k<=len;k<<=1) 14 { 15 cp wn=(cp){cos(2.0*pi*type/k),sin(2.0*pi*type/k)},w,t; 16 for(i=0;i<len;i+=k) 17 { 18 w=(cp){1,0}; 19 for(j=0;j<(k>>1);j++,w=w*wn) 20 { 21 t=w*s[i+j+(k>>1)]; 22 s[i+j+(k>>1)]=s[i+j]-t; 23 s[i+j]=s[i+j]+t; 24 } 25 } 26 } 27 } 28 void FFT_Main(int len) 29 { 30 FFT(A,len,1); FFT(B,len,1); 31 for(int i=0;i<len;i++) C[i]=A[i]*B[i]; 32 FFT(C,len,-1); 33 for(int i=0;i<len;i++) C[i].x/=len; 34 } 35
$NTT$:
1 ll qpow(ll x,ll y,const ll &mod) 2 { 3 ll ans=1; 4 for(;y;x=x*x%mod,y>>=1) 5 if(y&1) ans=ans*x%mod; 6 return ans; 7 } 8 const ll p=998244353; 9 int r[N1]; 10 ll A[N1],B[N1],C[N1],mulwn[N1],invwn[N1],invl,inv2; 11 void Pre(int len,int L) 12 { 13 int i; ll inv,invy; 14 for(i=0;i<len;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(L-1)); 15 for(i=1;i<=len;i<<=1) 16 { 17 mulwn[i]=qpow(3,(p-1)/i,p); 18 exgcd(mulwn[i],p,inv,invy); 19 invwn[i]=(inv%p+p)%p; 20 } 21 exgcd(len,p,invl,invy); invl=(invl%p+p)%p; 22 } 23 void NTT(ll *s,int len,int type) 24 { 25 int i,j,k; ll w,t,wn; 26 for(i=0;i<len;i++) if(i<r[i]) swap(s[i],s[r[i]]); 27 for(k=2;k<=len;k<<=1) 28 { 29 wn=type>0?mulwn[k]:invwn[k]; 30 for(i=0;i<len;i+=k) 31 { 32 for(j=0,w=1;j<(k>>1);j++,w=w*wn%p) 33 { 34 t=w*s[i+j+(k>>1)]%p; 35 s[i+j+(k>>1)]=(s[i+j]-t+p)%p; 36 s[i+j]=(s[i+j]+t)%p; 37 } 38 } 39 } 40 } 41 void NTT_Main(int len) 42 { 43 NTT(A,len,1); NTT(B,len,1); 44 for(int i=0;i<len;i++) C[i]=A[i]*B[i]%p; 45 NTT(C,len,-1); 46 for(int i=0;i<len;i++) C[i]=C[i]*invl%p; 47 }