ARC101E题解
对于每个 \(k\) 分别算答案。
将 \(i\) 和 \(k-i\) 配对,问题变成了每一组最多选一个。
假设现在有 \(x\) 组只包含两个数,\(y\) 组只包含一个数,问题等价于在 \(x+y\) 个数中任意选,被选到的 \(x\) 附带一个 \(2\) 的权值。
直接枚举有几个选到了 \(x\),几个选到了 \(y\),答案就是:
\[\sum_{i=0}^{n}F[x][i]G[y][n-i]
\]
其中 \(F[n][m]\) 表示 \(n\) 个数加起来和为 \(m\) 的方案数,每个数的权值为 \(2^{[x_i>0]}\),\(G[n][m]\) 类似。
显然有的是 \(F[n][m]=2(\sum_{i=0}^{m-1}F[n-1][i])+F[n-1][m],G[n][m]=\sum_{i=0}^{m-1}G[n-1][i]+G[n-1][m]\)
复杂度 \(O(n^2)\) 可以通过。
#include<cstdio>
const int M=2005,mod=998244353;
int n,k,ans[M],S1[M],S2[M],F[M][M],G[M][M];
inline int calc(const int&n,const int&x,const int&y){
int ans(0);for(int i=0;i<=n;++i)ans=(ans+1ll*F[x][i]*G[y][n-i])%mod;return ans;
}
signed main(){
scanf("%d%d",&k,&n);S1[0]=S2[0]=F[0][0]=G[0][0]=1;
for(int i=1;i<=k;++i){
for(int j=1;j<=n;++j)S1[j]=(S1[j-1]+F[i-1][j])%mod,S2[j]=(S2[j-1]+G[i-1][j])%mod;
for(int j=0;j<=n;++j)F[i][j]=(2ll*(j?S1[j-1]:0)+F[i-1][j])%mod,G[i][j]=((j?S2[j-1]:0)+G[i-1][j])%mod;
}
for(int i=1;i<=k;++i){
const int&c=i/2;if(c*2==i)ans[i]=calc(n,c,k-2*c);else ans[i]=(calc(n,c,k-2*c-1)+calc(n-1,c,k-2*c-1))%mod;
}
for(int i=1;i<=k-1;++i)printf("%d\n",ans[i]);printf("%d\n",ans[k]);for(int i=k-1;i>=1;--i)printf("%d\n",ans[i]);
}