The 2021 CCPC 威海 M.810975 【容斥原理】

https://codeforces.com/gym/103428/problem/M

题意

\(n\) 场比赛,赢用 \(1\) 表示,输用 \(0\) 表示,需要求出有 \(m\) 场赢了,并且最多连赢的场次为 \(k\) 的方案数

思路

首先输的场数为 \(n-m\),那么就可以在 \(n-m+1\) 个位置里插入赢的 \(m\) 场比赛

不难想到方程:

\(x_1+x_2+...+x_{n-m+1}=m\),其中 \(0\leq x_i \leq k\)

要解方程,不难想到用容斥原理解决

第一种思路:

\(0\leq x_i \leq k\) 的反面转化成 \(x_i = k+1, k+2,...,m\),原方程就可以表示成 \(\sum_{j=1}^{n-m}x_j = m-x_i\),时间复杂度 \(O(n^2)\)

第二种思路:

\(0\leq x_i \leq k\) 的反面转化成 \(x_i \geq k + 1\),可以 \(O(n)\) 求出答案

具体来说,先求出 {$x_i \leq k $ } 的解(所有情况减去不合法情况),又因为其中包含了不满足最大值为 \(k\) 的情况,所以再减去 {$x_i \leq k-1 $ } 的方案数

式子推出来是:(\(C_n^{n-m}-(C_{n-m+1}^1*C_{n-(k+1)}^{n-m} - C_{n-m+1}^2*C_{n-2*(k+1)}^{n-m}+...)\)) - ...(\(C_n^{n-m}-(C_{n-m+1}^1*C_{n-k}^{n-m} - C_{n-m+1}^2*C_{n-2*k}^{n-m}+...)\))

code

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e5 + 10, mod = 998244353;
int n, m, k;
ll fac[N], inv[N];

ll quickpow(ll a, ll x) {  //底数也开ll  因为可能是inv[] 
	ll ans = 1;
	while(x) {
		if(x & 1) {
			ans *= a;	
			ans %= mod;
		}
		a *= a;
		a %= mod;
		x /= 2;
	}
	return ans;
}

void init(int n) {
	fac[0] = 1;
	for(int i = 1; i <= n; i++) {
		fac[i] = fac[i - 1] * i % mod;
	}
	inv[n] = quickpow(fac[n], mod - 2);  
	for(int i = n - 1; i >= 1; i--) {
		inv[i] = inv[i + 1] * (i + 1) % mod;  
	}
	inv[0] = 1;
}

ll C(int n, int m) {
    if(n < m) return 0;
    return fac[n] * inv[m] % mod * inv[n - m] % mod;
}

inline ll solve(int k) {
    ll ans = C(n, n - m);
    for(int i = 1; i * k <= min(n, m); i++) {
        if(i % 2) ans = (ans - C(n - m + 1, i) * C(n - k * i, n - m) % mod + mod) % mod;
        else ans = (ans + C(n - m + 1, i) * C(n - k * i, n - m) % mod) % mod;
    }
    return ans;
}

int main() {
    init(1e5);
    scanf("%d%d%d", &n, &m, &k);
    if(k == 0) {
        if(m == 0) puts("1");
        else puts("0");
        system("pause");
        return 0;
    }
    if(n < m || m < k) {
        puts("0");
        system("pause");
        return 0;
    }
    printf("%lld\n", (solve(k + 1) - solve(k) + mod) % mod);
    system("pause");
    return 0;    
}
posted @ 2022-10-24 09:15  starlightlmy  阅读(136)  评论(0)    收藏  举报