CF1096E The Top Scorer 组合数 容斥

枚举小明得到得分数为x,枚举得分为x得有i人

主要问题是求出g(s,n,up) 有多少种方案满足: s个求,n个箱子,每个箱子容量为up

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+1000;
const ll mod=998244353;

ll fac[N],inv[N];
ll fast(ll x,ll n) {
    ll ans=1;
    for(;n;n>>=1,x=x*x%mod)
        if(n&1) ans=ans*x%mod;
    return ans;
}
ll init(){
    fac[0]=fac[1]=1;
    for(int i=2;i<N;i++) fac[i]=fac[i-1]*i%mod;
    inv[N-1]=fast(fac[N-1],mod-2);
    for(int i=N-2;i>=0;i--)
        inv[i]=(inv[i+1]*(i+1))%mod;
}
ll C(ll n,ll m) {
    if(n<0||m<0||m>n) return 0;
    if(!m||m==n) return 1;
    return ((fac[n]*inv[m]%mod*inv[n-m])%mod);
}
ll g(ll s,ll n,ll up) {
    if(!n&&!s) return 1;
    ll ans=0;
    for(int i=0,t=1;i<=n;i++,t*=-1)
        ans=(ans+t*C(n,i)%mod*C(s+n-1-i*(up+1),n-1)%mod+mod)%mod;
    return ans;
}

int main() {
    init();
    int n,s,r;cin>>n>>s>>r;ll ans=0;
    for(int x=r;x<=s;x++)
        for(int i=1;i<=n;i++) if(i*x<=s) {
        ans=(ans+C(n-1,i-1)*fast(i,mod-2)%mod*g(s-i*x,n-i,x-1))%mod;
    }
    ans=ans*fast(C(s+n-1-r,n-1),mod-2)%mod;
    cout<<ans<<endl;
}
View Code

猜你喜欢

转载自www.cnblogs.com/bxd123/p/12290554.html