2017 多小訓練第三場 HDU 6061 RXD and functions
阿新 • • 發佈:2019-02-08
NTT
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int mod=998244353; const int maxn=4e5+5; const int g=3; ll ni[maxn],fro[maxn],K[maxn],qp[30],F1[maxn],F2[maxn],ans[maxn]; int getlen(int a){ a<<=1; int ans=1; while(ans<a) ans<<=1; return ans; } ll qpow(ll a,ll b){ a%=mod; ll ans=1; while(b){ if(b&1) ans=ans*a%mod; a=a*a%mod; b>>=1; } return ans; } void init(){ for(int i=0;i<21;i++){ int t=1<<i; qp[i]=qpow(g,(mod-1)/t); } fro[0]=ni[0]=1; for(int i=1;i<maxn;i++){ fro[i]=fro[i-1]*i%mod; } ni[maxn-1]=qpow(fro[maxn-1],mod-2); for(int i=maxn-1;i>0;i--){ ni[i-1]=ni[i]*i%mod; } } void brc(ll *a,int l){ for(int i=1,j=l/2;i<l-1;i++){ if(i<j) swap(a[i],a[j]); int k=l/2; while(j>=k){ j-=k; k>>=1; } if(j<k) j+=k; } } void ntt(ll *y,int l,int on){ brc(y,l); int id=0; ll u,t,tmp; for(int h=2;h<=l;h<<=1){ id++; for(int j=0;j<l;j+=h){ ll w=1; for(int k=j;k<j+h/2;k++){ u=y[k]; t=w*y[k+h/2]%mod; y[k]=u+t; if(y[k]>=mod) y[k]-=mod; y[tmp=k+h/2]=u-t; if(y[tmp]<0) y[tmp]+=mod; w=w*qp[id]%mod; } } } if(on<0){ for(int i=1;i<l/2;i++) swap(y[i],y[l-i]); ll ni=qpow(l,mod-2); for(int i=0;i<l;i++){ y[i]=(y[i]*ni)%mod; } } } inline void debug(){ cout<<"yes"<<endl; } int main(int argc, char const *argv[]) { init(); int n,m; while(~scanf("%d",&n)){ for(int i=0;i<=n;i++){ scanf("%lld",K+i); } scanf("%d",&m); ll a=0; int x; for(int i=0;i<m;i++){ scanf("%d",&x); a-=x; if(a<0) a=(a+mod)%mod; } int len=getlen(n+1); if(a==0){ for(int i=0;i<=n;i++){ printf("%lld",K[i]); } printf("\n"); continue; } for(int i=0,aa=1;i<len;i++){ if(i<=n){ F1[i]=aa*ni[i]%mod; F2[i]=fro[n-i]*K[n-i]%mod; } else{ F1[i]=F2[i]=0; } aa=1LL*aa*a%mod; } ntt(F1,len,1); ntt(F2,len,1); for(int i=0;i<len;i++){ F1[i]=F1[i]*F2[i]%mod; } ntt(F1,len,-1); for(int i=0;i<=n;i++){ ans[i]=F1[i]; ans[i]=(ans[i]%mod+mod)*ni[n-i]%mod; } for(int i=0;i<=n;i++){ printf("%lld ",ans[n-i]); } printf("\n"); } return 0; }