Advertisement
yicongli

LG4705

Mar 18th, 2019
143
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.52 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. #define gc c=getchar()
  6. #define r(x) read(x)
  7. #define ll long long
  8.  
  9. template<typename T>
  10. inline void read(T&x){
  11.     x=0;T k=1;char gc;
  12.     while(!isdigit(c)){if(c=='-')k=-1;gc;}
  13.     while(isdigit(c)){x=x*10+c-'0';gc;}x*=k;
  14. }
  15.  
  16. const int N=4e5+7;
  17. const int g=3;
  18. const int p=998244353;
  19.  
  20. inline ll qpow(ll a,ll b){
  21.     ll ans=1;
  22.     while(b){
  23.         if(b&1)(ans*=a)%=p;
  24.         (a*=a)%=p;
  25.         b>>=1;
  26.     }
  27.     return ans;
  28. }
  29.  
  30. inline int add(int a,int b){
  31.     return (a+=b)>=p?a-p:a;
  32. }
  33.  
  34. inline int sub(int a,int b){
  35.     return (a-=b)<0?a+p:a;
  36. }
  37.  
  38. int r[N];
  39. int NOW_LEN;
  40. inline void ntt(int *A,int len,bool opt=1){
  41.     if(len!=NOW_LEN)for(int i=0;i<len;++i)r[i]=(r[i>>1]>>1)|((i&1)*(len>>1));
  42.     NOW_LEN=len;
  43.     for(int i=0;i<len;++i)if(i<r[i])swap(A[i],A[r[i]]);
  44.     for(int i=2;i<=len;i<<=1){
  45.         int wn=qpow(g,(p-1)/i),n=i>>1;
  46.         if(!opt)wn=qpow(wn,p-2);
  47.         for(int j=0;j<len;j+=i){
  48.             ll w=1;
  49.             for(int k=0;k<n;++k,w=w*wn%p){
  50.                 int u=A[j+k],v=A[j+k+n]*w%p;
  51.                 A[j+k]=add(u,v);
  52.                 A[j+k+n]=sub(u,v);
  53.             }
  54.         }
  55.     }
  56.     if(!opt){
  57.         ll inv=qpow(len,p-2);
  58.         for(int i=0;i<len;++i)A[i]=A[i]*inv%p;
  59.     }
  60. }
  61.  
  62. int Tmp_mul1[N],Tmp_mul2[N];
  63. inline void mul(int *A,int *B,int *C,int lenA,int lenB){
  64.     int len=1,lenC=lenA+lenB-1;
  65.     while(len<lenC)len<<=1;
  66.     memcpy(Tmp_mul1,A,lenA<<2);
  67.     memcpy(Tmp_mul2,B,lenB<<2);
  68.     memset(Tmp_mul1+lenA,0,(len-lenA)<<2);
  69.     memset(Tmp_mul2+lenB,0,(len-lenB)<<2);
  70.     ntt(Tmp_mul1,len);ntt(Tmp_mul2,len);
  71.     for(int i=0;i<len;++i)C[i]=(ll)Tmp_mul1[i]*Tmp_mul2[i]%p;
  72.     ntt(C,len,0);
  73.     memset(C+lenC,0,(len-lenC)<<2);
  74. }
  75.  
  76. int Tmp_inv[N];
  77. inline void inverse(int *A,int *Inv,int len){
  78.     memset(Inv,0,len<<2);
  79.     Inv[0]=qpow(A[0],p-2);
  80.     for(int i=2;i<len;i<<=1){
  81.         memcpy(Tmp_inv,A,i<<2);
  82.         memset(Tmp_inv+i,0,i<<2);
  83.         ntt(Inv,i<<1);ntt(Tmp_inv,i<<1);
  84.         for(int k=0;k<i<<1;++k)Inv[k]=(ll)Inv[k]*sub(2,(ll)Inv[k]*Tmp_inv[k]%p)%p;
  85.         ntt(Inv,i<<1,0);
  86.         memset(Inv+i,0,i<<2);
  87.     }
  88. }
  89.  
  90. inline void differentiate(int *A,int *Dif,int len){
  91.     for(int i=1;i<len;++i)Dif[i-1]=(ll)A[i]*i%p;
  92.     Dif[len-1]=0;
  93. }
  94.  
  95. int Inv_ln[N];
  96. inline void ln(int *A,int *Ln,int n){
  97.     inverse(A,Inv_ln,n);
  98.     differentiate(A,Ln,n);
  99.     mul(Ln,Inv_ln,Ln,n,n);
  100. }
  101.  
  102. int sta[51],top;
  103. int tmp[51][N];
  104.  
  105. int solve(int l,int r,int *A,int *B){
  106.     if(l==r){
  107.         B[0]=1;
  108.         B[1]=sub(0,A[l]);
  109.         return 2;
  110.     }
  111.     int mid=(l+r)>>1;
  112.     int ls=sta[top--];
  113.     int rs=sta[top--];
  114.     int len1=solve(l,mid,A,tmp[ls]);
  115.     int len2=solve(mid+1,r,A,tmp[rs]);
  116.     mul(tmp[ls],tmp[rs],B,len1,len2);
  117.     sta[++top]=ls;
  118.     sta[++top]=rs;
  119.     return len1+len2-1;
  120. }
  121.  
  122. int fac[N];
  123. int inv[N];
  124.  
  125. inline void init(int *A,int *B,int n,int k){
  126.     top=50;
  127.     for(int i=0;i<=top;++i)sta[i]=i;
  128.     solve(1,n,A,B);
  129.     int l=1;
  130.     while(l<=k)l<<=1;
  131.     ln(B,B,l);
  132.     for(int i=k;i;--i)B[i]=sub(0,B[i-1]);
  133.     B[0]=n;
  134.     for(int i=0;i<=k;++i)B[i]=(ll)B[i]*inv[i]%p;
  135. }
  136.  
  137. int a[N];
  138. int b[N];
  139. int F[N];
  140. int G[N];
  141.  
  142. int main(){
  143.     int n,m;r(n),r(m);
  144.     int Inv=qpow((ll)n*m%p,p-2);
  145.     for(int i=1;i<=n;++i)r(a[i]);
  146.     for(int i=1;i<=m;++i)r(b[i]);
  147.     int k;r(k);
  148.     fac[0]=1;
  149.     for(int i=1;i<=k;++i)fac[i]=(ll)fac[i-1]*i%p;
  150.     inv[1]=1;
  151.     for(int i=2;i<=k;++i)inv[i]=(ll)(p-p/i)*inv[p%i]%p;
  152.     inv[0]=1;
  153.     for(int i=1;i<=k;++i)inv[i]=(ll)inv[i]*inv[i-1]%p;
  154.     init(a,F,n,k);
  155.     init(b,G,m,k);
  156.     mul(F,G,F,k+1,k+1);
  157.     for(int i=1;i<=k;++i){
  158.         printf("%lld\n",(ll)F[i]*fac[i]%p*Inv%p);
  159.     }
  160. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement