#include #include #include using namespace std; /* * O(m log m) algorithm. For each mask x between 0 and m, let g(x) be the number of * values that are <= m and have all the 1 bits that x does. * * Then (g(x) choose n) is the number of ways to choose n student IDs such that * they at least have the bits in x on. We can then do a kind of * inclusion-exclusion to get the number of ways to choose n student IDs such * that they have exactly the bits in x on. * * Computing these mods is O(m). Applying these transforms with the SOS style * DP trick is O(m log m). */ constexpr int MOD = (119 << 23) + 1; int32_t modpow(int32_t b, int32_t e) { int32_t ans = 1; while (e > 0) { if (e % 2) { ans = 1LL * ans * b % MOD; } b = 1LL * b * b % MOD; e >>= 1; } return ans; } struct Chooser { Chooser(int32_t n): fact(n + 1), tcaf(n + 1) { fact[0] = 1; for (int i = 1; i <= n; ++i) { fact[i] = fact[i - 1] * i % MOD; } tcaf[n] = modpow(fact[n], MOD - 2); for (int i = n - 1; i >= 0; --i) { tcaf[i] = tcaf[i + 1] * (i + 1) % MOD; } } int32_t choose(int32_t n, int32_t k) const { if (k > n) { return 0; } else { return fact[n] * tcaf[k] % MOD * tcaf[n - k] % MOD; } } vector fact, tcaf; }; inline int32_t popcount(int32_t x) { return __builtin_popcount(x); } int main() { int32_t n, k, m; cin >> n >> k >> m; int32_t p2 = 1; while (p2 <= m) p2 <<= 1; Chooser chooser(p2); // g[x] = number of values <= m that have all the bits set in x vector g(p2, 0); for (int j = 0; j <= m; ++j) { g[j] = 1; } for (int32_t b = 1; b < p2; b <<= 1) { for (int32_t i = 0; i < p2; ++i) { if ((i & b) == 0) { g[i] += g[i ^ b]; } } } for (int i = 0; i < p2; ++i) { g[i] = chooser.choose(g[i], n); if (popcount(i) % 2) g[i] = MOD - g[i]; } vector f = g; for (int32_t b = 1; b < p2; b <<= 1) { for (int32_t i = 0; i < p2; ++i) { if ((i & b) == 0) { f[i] += f[i ^ b]; if (f[i] >= MOD) f[i] -= MOD; } } } for (int i = 0; i < p2; ++i) { if (popcount(i) % 2) f[i] = MOD - f[i]; } int64_t ans = 0; for (int i = (1 << k) - 1; i <= m; ++i) { if (popcount(i) >= k) { ans += f[i]; if (ans >= MOD) ans -= MOD; } } ans = ans * chooser.fact[n] % MOD; cout << ans << '\n'; return 0; }