生成函数这个东西太好用了~
code:
#include <bits/stdc++.h> #define ll long long #define setIO(s) freopen(s".in","r",stdin) using namespace std; const int mod=998244353,G=3,N=1000003; int A[N],B[N],F[N],g[N],inv2,C[N],D[N],tmp1[N]; inline int qpow(int x,int y) { int tmp=1; for(;y;y>>=1,x=(ll)x*x%mod) if(y&1) tmp=1ll*tmp*x%mod; return tmp; } inline int INV(int x) { return qpow(x,mod-2); } void NTT(int *a,int len,int flag) { int i,j,k,mid; for(i=k=0;i<len;++i) { if(i>k) swap(a[i],a[k]); for(j=len>>1;(k^=j)<j;j>>=1); } for(mid=1;mid<len;mid<<=1) { int wn=qpow(G,(mod-1)/(mid<<1)); if(flag==-1) wn=INV(wn); for(i=0;i<len;i+=mid<<1) { int w=1; for(j=0;j<mid;++j) { int x=a[i+j], y=1ll*w*a[i+j+mid]%mod; a[i+j]=1ll*(x+y)%mod, a[i+j+mid]=1ll*(x-y+mod)%mod; w=1ll*w*wn%mod; } } } if(flag==-1) { int rev=INV(len); for(i=0;i<len;++i) a[i]=1ll*a[i]*rev%mod; } } void getinv(int *a,int *b,int len) { if(len==1) { b[0]=INV(a[0]); return; } getinv(a,b,len>>1); int i,j; for(i=0;i<(len<<1);++i) C[i]=D[i]=0; for(i=0;i<len;++i) C[i]=a[i], D[i]=b[i]; NTT(C,len<<1,1); NTT(D,len<<1,1); for(i=0;i<(len<<1);++i) C[i]=1ll*C[i]*D[i]%mod*D[i]%mod; NTT(C,len<<1,-1); for(i=0;i<len;++i) b[i]=((b[i]<<1)%mod-C[i]+mod)%mod; } void getsqrt(int *a,int *b,int len) { if(len==1) { b[0]=1; return; } getsqrt(a,b,len>>1); int i,j; for(i=0;i<(len<<1);++i) A[i]=B[i]=0; getinv(b,B,len); for(i=0;i<len;++i) A[i]=a[i]; NTT(A,len<<1,1); NTT(B,len<<1,1); for(i=0;i<(len<<1);++i) A[i]=1ll*A[i]*B[i]%mod; NTT(A,len<<1,-1); for(i=0;i<len;++i) b[i]=1ll*(b[i]+A[i])%mod*inv2%mod; } int main() { // setIO("input"); inv2=INV(2); int i,j,n,m,limit; scanf("%d%d",&n,&m); for(i=1;i<=n;++i) { int x; scanf("%d",&x); if(x<=m) g[x]=1; } g[0]=1; for(i=1;i<=m;++i) g[i]=mod-1ll*4*g[i]; for(limit=1;limit<=m;limit<<=1); getsqrt(g,tmp1,limit); tmp1[0]=(tmp1[0]+1)%mod; getinv(tmp1,F,limit); for(i=1;i<=m;++i) printf("%d ",1ll*2*F[i]%mod); return 0; }