Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<bits/stdc++.h>
- using namespace std;
- #define gc c=getchar()
- #define r(x) read(x)
- #define ll long long
- template<typename T>
- inline void read(T&x){
- x=0;T k=1;char gc;
- while(!isdigit(c)){if(c=='-')k=-1;gc;}
- while(isdigit(c)){x=x*10+c-'0';gc;}x*=k;
- }
- const int N=4e5+7;
- const int g=3;
- const int p=998244353;
- inline ll qpow(ll a,ll b){
- ll ans=1;
- while(b){
- if(b&1)(ans*=a)%=p;
- (a*=a)%=p;
- b>>=1;
- }
- return ans;
- }
- inline int add(int a,int b){
- return (a+=b)>=p?a-p:a;
- }
- inline int sub(int a,int b){
- return (a-=b)<0?a+p:a;
- }
- int r[N];
- int NOW_LEN;
- inline void ntt(int *A,int len,bool opt=1){
- if(len!=NOW_LEN)for(int i=0;i<len;++i)r[i]=(r[i>>1]>>1)|((i&1)*(len>>1));
- NOW_LEN=len;
- for(int i=0;i<len;++i)if(i<r[i])swap(A[i],A[r[i]]);
- for(int i=2;i<=len;i<<=1){
- int wn=qpow(g,(p-1)/i),n=i>>1;
- if(!opt)wn=qpow(wn,p-2);
- for(int j=0;j<len;j+=i){
- ll w=1;
- for(int k=0;k<n;++k,w=w*wn%p){
- int u=A[j+k],v=A[j+k+n]*w%p;
- A[j+k]=add(u,v);
- A[j+k+n]=sub(u,v);
- }
- }
- }
- if(!opt){
- ll inv=qpow(len,p-2);
- for(int i=0;i<len;++i)A[i]=A[i]*inv%p;
- }
- }
- int Tmp_mul1[N],Tmp_mul2[N];
- inline void mul(int *A,int *B,int *C,int lenA,int lenB){
- int len=1,lenC=lenA+lenB-1;
- while(len<lenC)len<<=1;
- memcpy(Tmp_mul1,A,lenA<<2);
- memcpy(Tmp_mul2,B,lenB<<2);
- memset(Tmp_mul1+lenA,0,(len-lenA)<<2);
- memset(Tmp_mul2+lenB,0,(len-lenB)<<2);
- ntt(Tmp_mul1,len);ntt(Tmp_mul2,len);
- for(int i=0;i<len;++i)C[i]=(ll)Tmp_mul1[i]*Tmp_mul2[i]%p;
- ntt(C,len,0);
- memset(C+lenC,0,(len-lenC)<<2);
- }
- int Tmp_inv[N];
- inline void inverse(int *A,int *Inv,int len){
- memset(Inv,0,len<<2);
- Inv[0]=qpow(A[0],p-2);
- for(int i=2;i<len;i<<=1){
- memcpy(Tmp_inv,A,i<<2);
- memset(Tmp_inv+i,0,i<<2);
- ntt(Inv,i<<1);ntt(Tmp_inv,i<<1);
- for(int k=0;k<i<<1;++k)Inv[k]=(ll)Inv[k]*sub(2,(ll)Inv[k]*Tmp_inv[k]%p)%p;
- ntt(Inv,i<<1,0);
- memset(Inv+i,0,i<<2);
- }
- }
- inline void differentiate(int *A,int *Dif,int len){
- for(int i=1;i<len;++i)Dif[i-1]=(ll)A[i]*i%p;
- Dif[len-1]=0;
- }
- int Inv_ln[N];
- inline void ln(int *A,int *Ln,int n){
- inverse(A,Inv_ln,n);
- differentiate(A,Ln,n);
- mul(Ln,Inv_ln,Ln,n,n);
- }
- int sta[51],top;
- int tmp[51][N];
- int solve(int l,int r,int *A,int *B){
- if(l==r){
- B[0]=1;
- B[1]=sub(0,A[l]);
- return 2;
- }
- int mid=(l+r)>>1;
- int ls=sta[top--];
- int rs=sta[top--];
- int len1=solve(l,mid,A,tmp[ls]);
- int len2=solve(mid+1,r,A,tmp[rs]);
- mul(tmp[ls],tmp[rs],B,len1,len2);
- sta[++top]=ls;
- sta[++top]=rs;
- return len1+len2-1;
- }
- int fac[N];
- int inv[N];
- inline void init(int *A,int *B,int n,int k){
- top=50;
- for(int i=0;i<=top;++i)sta[i]=i;
- solve(1,n,A,B);
- int l=1;
- while(l<=k)l<<=1;
- ln(B,B,l);
- for(int i=k;i;--i)B[i]=sub(0,B[i-1]);
- B[0]=n;
- for(int i=0;i<=k;++i)B[i]=(ll)B[i]*inv[i]%p;
- }
- int a[N];
- int b[N];
- int F[N];
- int G[N];
- int main(){
- int n,m;r(n),r(m);
- int Inv=qpow((ll)n*m%p,p-2);
- for(int i=1;i<=n;++i)r(a[i]);
- for(int i=1;i<=m;++i)r(b[i]);
- int k;r(k);
- fac[0]=1;
- for(int i=1;i<=k;++i)fac[i]=(ll)fac[i-1]*i%p;
- inv[1]=1;
- for(int i=2;i<=k;++i)inv[i]=(ll)(p-p/i)*inv[p%i]%p;
- inv[0]=1;
- for(int i=1;i<=k;++i)inv[i]=(ll)inv[i]*inv[i-1]%p;
- init(a,F,n,k);
- init(b,G,m,k);
- mul(F,G,F,k+1,k+1);
- for(int i=1;i<=k;++i){
- printf("%lld\n",(ll)F[i]*fac[i]%p*Inv%p);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement