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
| #include <bits/stdc++.h>
typedef long long ll;
const int N = 8e5 + 233, P = 998244353;
inline ll fpow(ll x, int y) { ll ret = 1; for ( ; y; y >>= 1, x = x * x % P) if (y & 1) ret = ret * x % P; return ret; }
const int Gp = 3, Gpi = fpow(Gp, P - 2);
int rev[N], L, lim;
inline void init(int n) { L = 0, lim = 1; while (lim < n) lim <<= 1, ++L; for (int i = 1; i < lim; ++i) rev[i] = (rev[i >> 1] >> 1) ((i & 1) << (L - 1)); }
inline void NTT(ll f[], int o) { for (int i = 1; i < lim; ++i) if (i < rev[i]) std::swap(f[i], f[rev[i]]); for (int i = 1; i < lim; i <<= 1) { ll T = fpow(o == 1 ? Gp : Gpi, (P - 1) / (i << 1)); for (int j = 0; j < lim; j += i << 1) { ll w = 1; for (int k = 0; k < i; ++k, w = w * T % P) { ll nx = f[j + k], ny = f[i + j + k] * w % P; f[j + k] = nx + ny >= P ? nx + ny - P : nx + ny; f[i + j + k] = nx - ny >= 0 ? nx - ny : nx - ny + P; } } } if (o == -1) { ll inv = fpow(lim, P - 2); for (int i = 0; i < lim; ++i) f[i] = f[i] * inv % P; } }
void get_inv(ll F[], ll G[], int n) { if (n == 1) { G[0] = fpow(F[0], P - 2); return; } get_inv(F, G, (n + 1) >> 1); static ll T[N]; init(n << 1); for (int i = 0; i < lim; ++i) T[i] = i < n ? F[i] : 0; NTT(G, 1), NTT(T, 1); for (int i = 0; i < lim; ++i) G[i] = ((2 - G[i] * T[i]) % P + P) * G[i] % P; NTT(G, -1); for (int i = n; i < lim; ++i) G[i] = 0; }
int n; ll A[N], B[N], C[N], D[N], E[N], F[N];
void solve(int n) { if (n == 1) return A[0] = 1, void(); solve((n + 1) >> 1); init(n << 1); for (int i = 0; i < lim; ++i) B[i] = C[i] = D[i] = E[i] = F[i] = 0; for (int i = 0; i < n; ++i) { if (i * 2 < n) B[i * 2] = A[i]; if (i * 3 < n) C[i * 3] = A[i]; } NTT(A, 1), NTT(B, 1), NTT(C, 1); for (int i = 0; i < lim; ++i) { D[i] = (A[i] * A[i] % P * A[i] % P + 3 * B[i] * A[i] % P + 2 * C[i]) % P; E[i] = (3 * A[i] * A[i] % P + 3 * B[i]) % P; } NTT(A, -1), NTT(D, -1), NTT(E, -1); for (int i = lim - 1; i; --i) D[i] = D[i - 1], E[i] = E[i - 1]; D[0] = 6; E[0] = P - 6; for (int i = 0; i < lim; ++i) D[i] = (D[i] - 6 * A[i] % P + P) % P; get_inv(E, F, lim); NTT(D, 1), NTT(F, 1); for (int i = 0; i < lim; ++i) F[i] = (P - D[i] * F[i] % P) % P; NTT(F, -1); for (int i = 0; i < lim; ++i) A[i] = (A[i] + F[i]) % P; for (int i = n; i < lim; ++i) A[i] = 0; }
int main() { std::cin >> n; init(n); solve(n + 1); std::cout << A[n] << std::endl; return 0; }
|