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
| #include <bits/stdc++.h>
const int kMaxN = 1e7 + 5, kMod = 998244353;
int n, m; int fac[kMaxN], ifac[kMaxN], s[kMaxN];
int qpow(int bs, int64_t idx = kMod - 2) { int ret = 1; for (; idx; idx >>= 1, bs = (int64_t)bs * bs % kMod) if (idx & 1) ret = (int64_t)ret * bs % kMod; return ret; }
inline int add(int x, int y) { return (x + y >= kMod ? x + y - kMod : x + y); } inline int sub(int x, int y) { return (x >= y ? x - y : x - y + kMod); } inline void inc(int &x, int y) { (x += y) >= kMod ? x -= kMod : x; } inline void dec(int &x, int y) { (x -= y) < 0 ? x += kMod : x; }
int C(int m, int n) { if (m < n || m < 0 || n < 0) return 0; return 1ll * fac[m] * ifac[n] % kMod * ifac[m - n] % kMod; }
void prework(int n = 1e7) { fac[0] = 1; for (int i = 1; i <= n; ++i) fac[i] = 1ll * fac[i - 1] * i % kMod; ifac[n] = qpow(fac[n]); for (int i = n; i; --i) ifac[i - 1] = 1ll * ifac[i] * i % kMod; }
int S(int l, int r) { l = std::max(l, 0), r = std::min(r, n); return l <= r ? sub(s[r], !l ? 0 : s[l - 1]) : 0; }
int calc(int n, int l, int r, int L, int R) { l += n, r += n; if (l % 2 != 0) ++l; if (r % 2 != 0) ++r; l /= 2, r /= 2; int ret = 0; for (int k = -((n + R) / (R - L)); k <= (n + R) / (R - L); ++k) { inc(ret, sub(S(l + k * (R - L), r + k * (R - L)), S(l + k * (R - L) - R, r + k * (R - L) - R))); } return ret; }
void dickdreamer() { std::cin >> n >> m; --n; for (int i = 0; i <= n; ++i) s[i] = add(!i ? 0 : s[i - 1], C(n, i)); std::cout << calc(n, -1, (m + 1) / 2 - 1, -2, (m + 1) / 2) << '\n'; }
int32_t main() { #ifdef ORZXKR freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout); #endif std::ios::sync_with_stdio(0), std::cin.tie(0), std::cout.tie(0); int T = 1; prework(); while (T--) dickdreamer(); return 0; }
|