[SDOI移动金币 链接 vijos 思路 阶梯博弈,dp统计. 参见wxyww 代码 #include bits/stdc++.husing namespace std;const int N = 2e5 + 7, mod = 1e9 + 9;int read() { int x = 0, f = 1; char s = getchar(); for (;s '9' || s '0'; s = ge
[SDOI移动金币
链接
vijos
思路
阶梯博弈,dp统计.
参见wxyww
代码
#include <bits/stdc++.h> using namespace std; const int N = 2e5 + 7, mod = 1e9 + 9; int read() { int x = 0, f = 1; char s = getchar(); for (;s > '9' || s < '0'; s = getchar()) if (s == '-') f = -1; for (;s >= '0' && s <= '9'; s = getchar()) x = x * 10 + s - '0'; return x * f; } int n, m, f[20][N], jc[N], inv[N]; int q_pow(int a, int b) { int ans = 1; while (b) { if (b & 1) ans = 1LL * a * ans % mod; a = 1LL * a * a % mod; b >>= 1; } return ans; } int C(int n, int m) {return 1LL * jc[n] * inv[m] % mod * inv[n-m] % mod;} int main() { n = read(), m = read(); jc[0] = inv[0] = jc[1] = inv[1] = 1; for (int i = 2; i <= n; ++i) { jc[i] = 1LL * jc[i-1] * i % mod; inv[i] = q_pow(jc[i], mod - 2); } int ans = C(n, m); n -= m; int num = (m + 1) >> 1; f[0][0] = 1; for (int i = 1; i <= 19; ++i) { for (int j = 0; j <= n; ++j) { for (int k = 0; (k << i - 1) <= j && k <= num; k += 2) { f[i][j] += 1LL * f[i-1][j - (k << i - 1)] * C(num, k) % mod; f[i][j] %= mod; } } } for (int i = 0; i <= n; ++i) { ans -= 1LL * f[19][i] * C(n + m / 2 - i, m / 2) % mod; ans = (ans + mod) % mod; } printf("%lld", ans); return 0; }