题解:P14686 [ICPC 2025 Yokohama R] Charity Raffle
Claire0918 · · 题解
我们发现有且仅有如下情况不合法:
容易想到计算
前面一项考虑容斥,钦定
后面一项考虑先枚举最大值
注意到上式不为
Code:
#include<bits/stdc++.h>
#define mem(a, v) memset(a, v, sizeof(a))
using namespace std;
const int maxn = 1e6 + 10, maxk = 1e6 + 10, mod = 998244353;
int n, k, m, res = 0;
int fac[(maxn << 1) + maxk], ifac[(maxn << 1) + maxk];
template<typename Tp_x, typename Tp_y>
inline int mod_add(Tp_x x, Tp_y y){
return x += y, x >= mod ? x -= mod : x;
}
template<typename Tp_x, typename Tp_y>
inline int self_mod_add(Tp_x &x, Tp_y y){
return x = mod_add(x, y);
}
template<typename Tp, typename... Arg>
inline int mod_add(Tp x, Arg ...args){
return x += mod_add(args...), x >= mod ? x -= mod : x;
}
inline long long ksm(long long a, long long b){
long long res = 1;
for (;b; b & 1 && (res = res * a % mod), a = a * a % mod, b >>= 1);
return res;
}
inline long long inv(long long x){
return ksm(x, mod - 2);
}
inline long long c(int n, int m){
return n >= m && m >= 0 ? (long long)fac[n] * ifac[m] % mod * ifac[n - m] % mod : 0;
}
int main(){
scanf("%d %d %d", &n, &k, &m), fac[0] = 1;
for (int i = 1; i <= k + (n << 1); i++){
fac[i] = (long long)fac[i - 1] * i % mod;
}
ifac[k + (n << 1)] = inv(fac[k + (n << 1)]);
for (int i = k + (n << 1) - 1; ~i; i--){
ifac[i] = (long long)ifac[i + 1] * (i + 1) % mod;
}
for (int i = 0; i <= n && i * (m + 1) <= k; i++){
const int val = c(n, i) * c(k - i * (m + 1) + n - 1, n - 1) % mod;
self_mod_add(res, i & 1 ? mod - val : val);
}
for (int i = 1; i <= m; i++){
for (int s = 0; s + 1 <= n && (k - s * i + s - i >= 0 || k - s * i - i - 1 >= 0); s++){
const int val = c(n, s + 1) * mod_add(c(k - s * i + s + n - 1 - i, n - 1), mod - c(k - s * i + n - 2 - i, n - 1)) % mod;
self_mod_add(res, s & 1 ? val : mod - val);
}
}
printf("%d", res);
return 0;
}