1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
| const int L=18,N=1<<L|10,P=998244353;
ll qpow(ll x,ll k=P-2) { ll res=1; for(;k;k>>=1,x=x*x%P) if(k&1) res=res*x%P; return res; }
int I[N],J[N]; int rev[N],w[N]; void Init(){ w[1<<(L-1)]=1; int t=qpow(3,(P-1)>>L); rep(i,(1<<(L-1))+1,1<<L) w[i]=1ll*w[i-1]*t%P; drep(i,(1<<(L-1))-1,1) w[i]=w[i<<1]; rep(i,J[0]=1,N-1) J[i]=1ll*J[i-1]*i%P; I[N-1]=qpow(J[N-1]); drep(i,N-1,1) I[i-1]=1ll*I[i]*i%P; } int Init(int n){ int R=1,c=-1; while(R<=n) R<<=1,c++; rep(i,0,R-1) rev[i]=(rev[i>>1]>>1)|((i&1)<<c); return R; } void NTT(int n,V &A,int f) { static ll a[N]; if((int)A.size()<n) A.resize(n); rep(i,0,n-1) a[rev[i]]=A[i]; for(int i=1;i<n;i<<=1) { int *e=w+i; for(int l=0;l<n;l+=i*2) { for(int j=l;j<l+i;++j) { int t=a[j+i]*e[j-l]%P; a[j+i]=a[j]-t; a[j]+=t; } } } rep(i,0,n-1) A[i]=a[i]%P,Mod2(A[i]); if(f==-1) { reverse(A.begin()+1,A.end()); ll base=1ll*I[n]*J[n-1]%P; rep(i,0,n-1) A[i]=A[i]*base%P; } }
V operator + (V a,const V &b) { if(a.size()<b.size()) a.resize(b.size()); rep(i,0,b.size()-1) a[i]+=b[i],Mod1(a[i]); return a; } V operator - (V a,const V &b) { if(a.size()<b.size()) a.resize(b.size()); rep(i,0,b.size()-1) a[i]-=b[i],Mod2(a[i]); return a; } V operator * (V a,V b) { int n=a.size()-1,m=b.size()-1; int R=Init(n+m); NTT(R,a,1),NTT(R,b,1); rep(i,0,R-1) a[i]=1ll*a[i]*b[i]%P; NTT(R,a,-1),a.resize(n+m+1); return a; } void println(const V &a){ for(int i:a) printf("%d ",i); puts(""); } V read(int n){ V A(n); rep(i,0,n-1) A[i]=rd(); return A; } V operator ~ (V a) { int n=a.size(),m=(n+1)>>1; if(n==1) return {(int)qpow(a[0])}; V b=a; b.resize(m),b=~b; int R=Init(n*2); NTT(R,a,1),NTT(R,b,1); rep(i,0,R-1) a[i]=(P+2-1ll*a[i]*b[i]%P)*b[i]%P; NTT(R,a,-1),a.resize(n); return a; }
int Div2(int x){ return (x&1?x+P:x)/2; } V Sqrt(V a){ if(a.size()==1) return a; int n=a.size(); V b=a; b.resize((n+1)/2),b=Sqrt(b),b.resize(n); a=a*~b; a.resize(n); rep(i,0,b.size()-1) a[i]+=b[i],Mod1(a[i]); rep(i,0,n-1) a[i]=Div2(a[i]); return a; }
int Pow[N],IPow[N];
int main(){ int n=1e5; Init(); Pow[0]=Pow[1]=IPow[0]=IPow[1]=1; for(int i=2,x=2,y=(P+1)/2;i<N;i++,x*=2,Mod1(x),y=Div2(y)) { Pow[i]=1ll*Pow[i-1]*x%P; IPow[i]=1ll*IPow[i-1]*y%P; } V F(n+1); rep(i,0,n) F[i]=1ll*I[i]*IPow[i]%P; F=F*F,F.resize(n+1); rep(i,0,n) F[i]=1ll*F[i]*Pow[i]%P; F=Sqrt(F); rep(i,1,n) printf("%d\n",int(1ll*F[i]*J[i]%P)); }
|