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;
}

转载于:https://www.cnblogs.com/pkh68/p/10561567.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值