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
| int n,g[N],tr[N],F[N],G[N],H[N],f[N];
inline int ksm(int a,int b,int mod){int res=1;while(b){if(b&1)res=1ll*a*res%mod;a=1ll*a*a%mod;b>>=1;}return res;} inline int inv(int a){return ksm(a,mod-2,mod);} inline void Gettr(int n){ for(int i=0;i<n;i++) tr[i]=(tr[i>>1]>>1)|((i&1)?(n>>1):0); } inline void NTT(int *f,int n,int op){ rep(i,0,n-1) if(i<tr[i]) swap(f[i],f[tr[i]]); for(int i=2;i<=n;i<<=1){ int x=ksm(gg,(mod-1)/i,mod),l=i>>1;if(op==0) x=inv(x); for(int j=0;j<n;j+=i){ int now=1; for(int k=j;k<j+l;k++){ int tt=1ll*now*f[k+l]%mod; f[k+l]=(f[k]-tt)%mod;f[k]=(f[k]+tt)%mod; now=1ll*now*x%mod; } } } if(op==0){ int invn=inv(n);rep(i,0,n-1) f[i]=1ll*f[i]*invn%mod; } } inline void Solve(int l,int r){ if(l==r){if(l==0)f[0]=1;return;} int mid=(l+r)>>1,len=r-l+1; Solve(l,mid);rep(i,0,len-1) F[i]=G[i]=0; rep(i,0,mid-l) F[i]=f[i+l]; rep(i,0,len-1) G[i]=g[i]; int nl=1;while(nl<len*2){nl<<=1;}Gettr(nl); rep(i,mid-l+1,nl-1) F[i]=0;rep(i,len,nl-1) G[i]=0; NTT(F,nl,1);NTT(G,nl,1); rep(i,0,nl-1) F[i]=1ll*F[i]*G[i]%mod; NTT(F,nl,0);rep(i,mid+1-l,r-l) (f[i+l]+=F[i])%=mod; Solve(mid+1,r); }
int main(){ read(n);rep(i,1,n-1) read(g[i]); Solve(0,n-1); rep(i,0,n-1) printf("%d ",(f[i]+mod)%mod); return 0; }
|