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 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
| #include <iostream> #include <cstdio> #include <algorithm> #define int long long
using namespace std;
const int N = 1e6 + 10, mod = 998244353, G = 3; int invG; int tr[N]; int n, m, D; int fac[N], ifac[N], inv[N]; int f[N], g[N];
int qpow(int a, int b) { int res = 1; while (b) { if (b & 1) res = res * a % mod; a = a * a % mod; b >>= 1; } return res; }
int add(int a, int b) { return a + b >= mod ? a + b - mod : a + b; }
int sub(int a, int b) { return a - b < 0 ? a - b + mod : a - b; }
void ntt(int *f, int n, int op) { for (int i = 0; i < n; ++i) { tr[i] = (tr[i >> 1] >> 1) | ((i & 1) ? (n >> 1) : 0); } for (int i = 0; i < n; ++i) { if (i < tr[i]) swap(f[i], f[tr[i]]); } for (int p = 2; p <= n; p <<= 1) { int len = p / 2; int tG = qpow(op ? G : invG, (mod - 1) / p); for (int l = 0; l < n; l += p) { int buf = 1; for (int k = l; k < l + len; ++k) { int tmp = buf * f[k + len] % mod; f[k + len] = sub(f[k], tmp); f[k] = add(f[k], tmp); buf = buf * tG % mod; } } } int invn = qpow(n, mod - 2); if (op == 0) { for (int i = 0; i < n; ++i) f[i] = f[i] * invn % mod; } }
void px(int *f, int *g, int n) { for (int i = 0; i < n; ++i) f[i] = f[i] * g[i] % mod; }
void mul(int *f, int *g, int n) { int m = n; for (n = 1; n <= m * 2; n <<= 1); fill(f + m, f + n, 0); fill(g + m, g + n, 0); ntt(f, n, 1), ntt(g, n, 1); px(f, g, n); ntt(f, n, 0); }
signed main() { cin >> D >> n >> m; if (n - 2 * m < 0) return 0; if (n - 2 * m >= D) return cout << qpow(D, n), 0; fac[1] = fac[0] = ifac[1] = ifac[0] = inv[1] = 1; invG = qpow(G, mod - 2); for (int i = 2; i <= D + 1; ++i) { fac[i] = fac[i - 1] * i % mod; inv[i] = (mod - mod / i) * inv[mod % i] % mod; ifac[i] = ifac[i - 1] * inv[i] % mod; } for (int i = 0; i <= D; ++i) { if (i & 1) { f[i] = sub(mod, qpow(sub(D, 2 * i), n) * ifac[i] % mod); } else { f[i] = qpow(sub(D, 2 * i), n) * ifac[i] % mod; } g[i] = ifac[i]; } mul(f, g, D + 1); for (int i = 0; i <= D; ++i) { f[i] = f[i] * fac[D] % mod * qpow(qpow(2, i), mod - 2) % mod * ifac[D - i] % mod * fac[i] % mod; } for (int i = 0; i <= D; ++i) { if (i & 1) { g[D - i] = sub(mod, ifac[i]); } else g[D - i] = ifac[i]; } mul(f, g, D + 1); int ans = 0; for (int i = 0; i <= n - 2 * m; ++i) { ans = add(ans, f[D + i] * ifac[i] % mod); } cout << ans << endl; return 0; }
|