0%

【题解】CCPC2021威海站 M - 810975

题目链接

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

题目大意

一个长度为 \(n\)\(01\) 串,有 \(m\) 个位置是 \(1\) ,最长的 \(1\) 的连续段长度是 \(k\) ,求方案数。

数据范围

  • \(0 \le n, m, k \le 10^5\)

解题思路

参考代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
const int MAXN = 2e5 + 10;
const int Mod = 998244353;

int fac[MAXN], invf[MAXN];

ll ksm(ll x, ll y) {
ll res = 1;
while (y) {
if (y & 1) {
res = res * x % Mod;
}
x = x * x % Mod;
y >>= 1;
}
return res;
}
ll inv(ll x) {
return ksm(x, Mod - 2);
}

void init(int lim) {
fac[0] = 1;
for (int i = 1; i <= lim; i++) {
fac[i] = 1ll * fac[i - 1] * i % Mod;
}
invf[lim] = inv(fac[lim]);
for (int i = lim - 1; i >= 0; i--) {
invf[i] = 1ll * invf[i + 1] * (i + 1) % Mod;
}
}

int C(int x, int y) {
if (x < y) return 0;
return 1ll * fac[x] * invf[y] % Mod * invf[x - y] % Mod;
}

int calc(int x, int y) {
return C(x + y - 1, y - 1);
}

int solve(int n, int m, int k) {
int res = 0;
for (int i = 0; i <= n - m + 1; i++) {
int coef = (i & 1) ? -1 : 1;
int add = 1ll * C(n - m + 1, i) * calc(m - i * (k + 1), n - m + 1) % Mod;
if (coef == -1) {
add = Mod - add;
}
res = (res + add) % Mod;
}
return res;
}

int main() {
init(MAXN - 1);

int n, m, k;
cin >> n >> m >> k;

int ans = (solve(n, m, k) - solve(n, m, k - 1) + Mod) % Mod;
printf("%d\n", ans);

return 0;
}