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 115 116 117 118 119 120 121 122
| #include<bits/stdc++.h> char obuf[1<<21],*oS=obuf,*oT=oS+(1<<21)-1; #define flush() (fwrite(obuf,1,oS-obuf,stdout),oS=obuf,void()) #define getchar() (iS==iT?(iT=(iS=ibuf)+fread(ibuf,1,S,stdin),(iS==iT?EOF:*iS++)):*iS++) #define putchar(x) (*oS++=(x),oS==oT?flush():void()) struct Flusher_{~Flusher_(){flush();}}flusher_; template<class T> inline void print(T x){ if(x<0)putchar('-'),x=-x; if(x>9)print(x/10); putchar(x%10+'0'); } template<class T> inline void print(T x,char c){print(x),putchar(c);} #define love % const int N=1e5+10,wyp=998244353; int n,len; struct z { int32_t x; z(int32_t x=0):x(x){} friend inline z operator*(z a,z b){return (int64_t)a.x*b.x love wyp;} friend inline z operator-(z a,z b){return (a.x-=b.x)<0?a.x+wyp:a.x;} friend inline z operator+(z a,z b){return (a.x+=b.x)>=wyp?a.x-wyp:a.x;} }h[N],ans[N],inv[N],fac[N],ifac[N]; inline z fpow(z a,int b){z s=1;for(;b;b>>=1,a=a*a)if(b&1)s=s*a;return s;} void init(int n){ fac[0]=ifac[0]=inv[0]=inv[1]=1; for(int i=2;i<n;i++)inv[i]=(wyp-wyp/i)*inv[wyp love i]; for(int i=1;i<n;i++)fac[i]=fac[i-1]*i,ifac[i]=ifac[i-1]*inv[i]; } namespace poly{ int len=1,rev[N<<2]; z w[N<<2]; struct vec:std::vector<z>{ using std::vector<z>::vector; inline void input(){for(size_t i=0;i<size();i++)scanf("%d",&((int&)this->operator[](i)));} inline void output(){for(size_t i=0;i<size();i++)printf("%d%c",this->operator[](i).x," \n"[i+1==size()]);} inline vec divx(){vec res=*this; return res.erase(res.begin()),res;} inline vec setl(size_t len){vec res=*this; return res.resize(len),res;} inline vec fun1(){vec res(this->begin()+1,this->end()); for(int i=0;i<res.size();i++)res[i].x=wyp-res[i].x; return res;} }; int init(int n){ int lim=1,k=0; while(lim<n)lim<<=1,++k; for(int i=0;i<lim;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(k-1)); for(;len<lim;len<<=1){ z wn=fpow(3,(wyp-1)/(len<<1)); w[len]=1; for(int i=1;i<len;i++)w[i+len]=w[i+len-1]*wn; }return lim; } void dft(vec &a,int lim){ a.resize(lim); for(int i=0;i<lim;i++)if(i<rev[i])std::swap(a[i],a[rev[i]]); for(int i=0;i<lim;i+=2){z x=a[i],y=a[i+1]*w[1];a[i]=x+y,a[i+1]=x-y;} for(int len=2;len<lim;len<<=1) for(int i=0;i<lim;i+=(len<<1)) for(int j=0;j<len;j++){ z x=a[i+j],y=a[i+j+len]*w[j+len]; a[i+j]=x+y,a[i+j+len]=x-y; } } void idft(vec &a,int lim){ z inv=fpow(lim,wyp-2); dft(a,lim),std::reverse(&a[1],&a[lim]); for(int i=0;i<lim;i++)a[i]=a[i]*inv; } vec operator+(vec a,const vec &b){ a.resize(std::max(a.size(),b.size())); for(int i=0;i<b.size();i++)a[i]=a[i]+b[i]; return a; } vec operator-(vec a,const vec &b){ a.resize(std::max(a.size(),b.size())); for(int i=0;i<b.size();i++)a[i]=a[i]-b[i]; return a; } vec operator*(vec a,vec b){ if(a.size()<20||b.size()<20||(uint64_t)a.size()+b.size()<400){ vec c(a.size()+b.size()-1); for(int i=0;i<a.size();i++) for(int j=0;j<b.size();j++) c[i+j]=c[i+j]+a[i]*b[j]; return c; } int len=a.size()+b.size()-1,lim=init(len); dft(a,lim),dft(b,lim); for(int i=0;i<lim;i++)a[i]=a[i]*b[i]; return idft(a,lim),a.resize(len),a; } vec inv(const vec &f,int len=-1){ if((len=~len?len:f.size())==1)return vec{fpow(f[0],wyp-2)}; vec a=inv(f,(len+1)>>1),b(&f[0],&f[len]); int lim=init((len<<1)-1); dft(a,lim),dft(b,lim); for(int i=0;i<lim;i++)a[i]=a[i]*(2-a[i]*b[i]); return idft(a,lim),a.resize(len),a; } vec inte(vec a){for(int i=a.size()-1;i;i--)a[i]=a[i-1]*::inv[i];return *a.begin()=0,a;} vec deri(vec a){for(int i=0;i<a.size()-1;i++)a[i]=a[i+1]*(i+1);return *a.rbegin()=0,a;} vec ln(const vec &f){return inte((deri(f)*inv(f)).setl(f.size()));} vec exp(const vec &f,int len=-1){ if((len=~len?len:f.size())==1)return vec{1}; vec a=exp(f,(len+1)>>1),b=a;b.resize(len),b=ln(b); for(int i=0;i<len;i++)b[i]=0-b[i]; b[0]=b[0]+1; for(int i=0;i<len;i++)b[i]=b[i]+f[i]; return (a*b).setl(len); } vec pow(vec a,int b){a=ln(a); for(int i=0;i<a.size();i++)a[i]=a[i]*b; return exp(a);} } using poly::vec; int main(){ #ifdef memset0 freopen("1.in","r",stdin); #endif std::cin>>n; init(n+10),len=n+5; vec Finv=poly::inv(vec(ifac+1,ifac+len+1).fun1()); for(int i=0;i<=n;i++)h[i]=Finv[i+1]; h[0]=h[0]-1; vec P(len); for(int i=0;i<len;i++)P[i]=(i&1?wyp-1:1)*inv[i+1]; P=poly::inv(P); vec Ppow=poly::pow(P,n+1); vec Pinv=poly::inv(P.fun1()); vec lpart=(Ppow*Pinv).setl(len); vec rpart=((poly::deri(P)*Pinv).setl(len)*lpart).setl(len); z tmp=fpow(n+1,wyp-2); for(int i=0;i<=n;i++)h[i]=h[i]-tmp*(lpart[i+1]*(n-i+1)+rpart[i+1]); vec f(n+1),g(n+1); for(int i=0;i<=n;i++)f[i]=((n-i)&1?wyp-1:1)*ifac[n-i]; for(int i=0;i<=n;i++)g[i]=fac[i]*h[i]; f=f*g; for(int i=0;i<n;i++)ans[i]=f[i+n]*fac[n]*ifac[i]; for(int i=0;i<n;i++)print(ans[i].x," \n"[i+1==n]); }
|