ARC102E Stop. Otherwise...

ARC102E Stop. Otherwise...

题面:Atcoder

解析

题意即让为每一个骰子选一个点数,使不存在两个骰子点数和为\(x\)的方案数。
考虑容斥,设当前组成和为\(x\)的方案数为\(t\)\(g(i)\)表示至少有\(i\)对和为\(x\)的方案数,那么有:

\[ans=\sum_{i=0}^{t}(-1)^i g(i) \]

这样得到的答案便是合法的方案数,现在考虑如何计算\(g(i)\),就是强制选\(i\)对,然后剩下随意分配即可,那么有:

\[g(i)={t \choose i}{n-2\times i+K-1 \choose K-1} \]

代码


#include<cstdio>
#define N 2005
using namespace std;
const int P=998244353,__=4000;
inline int In(){
	char c=getchar(); int x=0,ft=1;
	for(;c<'0'||c>'9';c=getchar()) if(c=='-') ft=-1;
	for(;c>='0'&&c<='9';c=getchar()) x=x*10+c-'0';
	return x*ft;
}
int K,n,ans[N],fac[N*2],inv[N*2];
inline int power(int x,int k){
	int s=1,t=x;
	for(;k;k>>=1,t=1ll*t*t%P) if(k&1) s=1ll*s*t%P;
	return s;
}
inline int C(int m,int n){
	return 1ll*fac[m]*inv[n]%P*inv[m-n]%P;
}
int main(){
	K=In(); n=In();
	fac[0]=1; for(int i=1;i<=__;++i) fac[i]=1ll*fac[i-1]*(i)%P;
	inv[__]=power(fac[__],P-2); for(int i=__-1;~i;--i) inv[i]=1ll*inv[i+1]*(i+1)%P;
	for(int i=2,t;i<=K+1;++i){
		t=i/2;
		for(int j=0,d=1;2*j<=n&&j<=t;++j,d=P-d)
		(ans[i]+=1ll*d*C(t,j)%P*C(n-2*j+K-1,K-1)%P)%=P;
		printf("%d\n",ans[i]);
	}
	for(int i=K;i>=2;--i) printf("%d\n",ans[i]);
	return 0;
}


posted @ 2019-03-19 21:33  pkh68  阅读(250)  评论(0编辑  收藏  举报