#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define rint register int
inline int rd(){
int x=0,f=1;
char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)) x=x*10+(ch^48),ch=getchar();
return x*f;
}
const int N=400010;
const int mod=998244353;
int n,g[N],f[N],a[N],b[N],rev[N],lim,lg;
LL qpow(LL n,LL k) {
LL res=1;for(;k;k>>=1,n=n*n%mod)if(k&1)res=res*n%mod;return res;
}
void NTT(int *a,int g,int n) {
for(rint i=0;i<n;++i)
if(i>rev[i])swap(a[i],a[rev[i]]);
for(rint i=1;i<n;i<<=1) {
int wn=qpow(g,(mod-1)/(i<<1));
for(rint j=0;j<n;j+=(i<<1)) {
int w0=1;
for(rint k=0;k<i;++k,w0=(1ll*w0*wn)%mod) {
int X=a[j+k],Y=1ll*w0*a[i+j+k]%mod;
a[j+k]=(X+Y)%mod;
a[i+j+k]=(X-Y+mod)%mod;
}
}
}
}
void CDQ_NTT(int l,int r) {
if(l==r)return;
int mid=(l+r)>>1;
CDQ_NTT(l,mid);
int mx=r-l+1;
for(lg=0,lim=1;lim<=mx;lim<<=1,++lg);
for(rint i=0;i<lim;++i)rev[i]=(rev[i>>1]>>1)|((i&1)<<(lg-1)),a[i]=b[i]=0;
for(rint i=l;i<=mid;++i)a[i-l]=f[i];
for(rint i=1;i<=r-l;++i)b[i-1]=g[i];
NTT(a,3,lim),NTT(b,3,lim);
for(rint i=0;i<lim;++i)a[i]=1ll*a[i]*b[i]%mod;
NTT(a,qpow(3,mod-2),lim);
for(rint i=0,inv=qpow(lim,mod-2);i<lim;++i)a[i]=1ll*a[i]*inv%mod;
for(rint i=mid+1;i<=r;++i)f[i]=(f[i]+a[i-l-1])%mod;
CDQ_NTT(mid+1,r);
}
signed main() {
n=rd();f[0]=1;
for(rint i=1;i<n;++i)g[i]=rd()%mod;
CDQ_NTT(0,n-1);
for(rint i=0;i<n;++i)printf("%d ",f[i]);
return 0;
}
分治FFT模板(无讲解)
猜你喜欢
转载自www.cnblogs.com/zzctommy/p/12550550.html
今日推荐
周排行