洛谷 P4705 玩游戏
// luogu-judger-enable-o2 // luogu-judger-enable-o2 #include <bits/stdc++.h> #define rap(i,s,n) for(int i=s;i<=n;i++) #define drap(i,n,s) for(int i=n;i>=s;i--) #define N 410000 #define P 998244353 #define lb(x) ((x&(-x))) #define ll long long #define m(s,k) memset(s,k,sizeof s) using namespace std; char xB[1<<15],*xS=xB,*xTT=xB; #define getc() (xS==xTT&&(xTT=(xS=xB)+fread(xB,1,1<<15,stdin),xS==xTT)?0:*xS++) #define isd(c) ((c>='0'&&c<='9')||(c=='-')) template<typename T> inline bool rd(T& xa){ char xchh; T f=1; while(xchh=getc(),(!isd(xchh))&&(xchh!=0)); if(xchh==0) return 0; if(xchh=='-') xchh=getc(),f=-1; xa=xchh-'0'; while(xchh=getc(),isd(xchh)) xa=xa*10+xchh-'0'; xa*=f; return 1; } ll mpow(ll a,ll k,ll p){ll res=1; while(k){if(k&1) res=res*a%p; k>>=1; a=a*a%p;} return res%p;} ll Inv(ll x){return mpow(x,P-2,P);} ll fac[N],inv[N],finv[N]; void Finit(int n){ fac[0]=1; rap(i,1,n) fac[i]=fac[i-1]*i%P; inv[1]=1; rap(i,2,n) inv[i]=inv[P%i]*(P-P/i)%P; finv[0]=1; rap(i,1,n) finv[i]=finv[i-1]*inv[i]%P; } namespace Poly{ ll c[N],f[N],f1[N],fi[N]; int rev[N],lim,l; void init(int n){ lim=1,l=0; while(lim<=n) lim<<=1,l++; rap(i,1,lim-1) rev[i]=(rev[i>>1]>>1)|((i&1)<<(l-1)); } void NTT(ll *A,int k){ rap(i,1,lim-1) if(i<rev[i]) swap(A[i],A[rev[i]]); for(int l=1;l<lim;l<<=1){ ll gn=mpow(3,(P-1)+k*(P-1)/l/2,P); for(int j=0;j<lim;j+=l*2){ ll g=1; for(int k=0;k<l;k++,g=g*gn%P){ ll x=A[k+j],y=A[k+j+l]*g%P; A[k+j]=(x+y)%P; A[k+j+l]=(x-y+P)%P; } } } if(k==-1) {ll tinv=Inv(lim); rap(i,0,lim-1) A[i]=A[i]*tinv%P;} } void MUL(ll *A,int n,ll *B,int m,ll *C){ init(n+m); NTT(A,1); NTT(B,1); rap(i,0,lim-1) C[i]=A[i]*B[i]%P; NTT(A,-1); NTT(B,-1); NTT(C,-1); } void MUL(ll *A,int n,ll *B,int m){ init(n+m); NTT(A,1); NTT(B,1); rap(i,0,lim-1) B[i]=B[i]*A[i]%P; NTT(A,-1); NTT(B,-1); } void INV(ll *A,ll *B,int n){ if(n==1){B[0]=Inv(A[0]); return;} INV(A,B,(n+1)>>1); init(2*n); m(c,0); rap(i,0,n-1) c[i]=A[i]; NTT(c,1); NTT(B,1); rap(i,0,lim-1) B[i]=(2-B[i]*c[i]+P)%P*B[i]%P; NTT(B,-1); rap(i,n,lim-1) B[i]=0; return; } void MUL(ll *A,int *a,int n){ int len=1; while(len<n) len<<=1; ll *f[N]; rap(i,1,len){f[i]=new ll[lb(i)<<2]; f[i][0]=1; f[i][1]=a[i];} for(int l=1;l<len;l<<=1){init(2*l); for(int j=l*2;j<=len;j+=l*2){ NTT(f[j-l],1); NTT(f[j],1); rap(i,0,lim-1) f[j][i]=f[j][i]*f[j-l][i]%P; NTT(f[j],-1); }} rap(i,0,n) A[i]=f[len][i]; return; } void DEAL(ll *A,int *a,int n,int k){ m(f,0); MUL(f,a,n); m(f1,0); rap(i,0,n-1) f1[i]=f[i+1]*(i+1)%P; m(fi,0); INV(f,fi,k+1); MUL(f1,n-1,fi,k,A); drap(i,k,1) A[i]=A[i-1]*inv[i]%P; rap(i,k+1,lim-1) A[i]=0; rap(i,1,k){A[i]=A[i]*i%P; if((i&1)==0) A[i]=P-A[i];} } } int n,m,K,a[N],b[N]; ll A[N],B[N],ans[N]; int main(){ rd(n); rd(m); rap(i,1,n) rd(a[i]); rap(i,1,m) rd(b[i]); rd(K); Finit(max(max(n,m),K)+100); Poly::DEAL(A,a,n,K); Poly::DEAL(B,b,m,K); rap(i,1,K) A[i]=A[i]*finv[i]%P,B[i]=B[i]*finv[i]%P; A[0]=n; B[0]=m; Poly::MUL(A,K,B,K,ans); ll tinv=Inv(1ll*n*m%P); rap(i,1,K) ans[i]=ans[i]*fac[i]%P*tinv%P; rap(i,1,K) printf("%lld\n",ans[i]); return 0; }
如果大家满意就关注我吧!