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]);
}
posted @ 2022-08-20 16:44  Prean  阅读(17)  评论(0编辑  收藏  举报
var canShowAdsense=function(){return !!0};