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
| #include <bits/stdc++.h>
#define int int64_t
const int kMaxN = 3e3 + 5;
int n, mod; int f[kMaxN][3], g[kMaxN][5], h[kMaxN][5];
constexpr int qpow(int bs, int64_t idx = mod - 2) { int ret = 1; for (; idx; idx >>= 1, bs = (int64_t)bs * bs % mod) if (idx & 1) ret = (int64_t)ret * bs % mod; return ret; }
inline int add(int x, int y) { return (x + y >= mod ? x + y - mod : x + y); } inline int sub(int x, int y) { return (x >= y ? x - y : x - y + mod); } inline void inc(int &x, int y) { (x += y) >= mod ? x -= mod : x; } inline void dec(int &x, int y) { (x -= y) < 0 ? x += mod : x; }
int C(int m, int n) { if (n == 0) return 1; else if (n == 1) return m; else if (n == 2) return 1ll * m * (m - 1) % mod * ((mod + 1) / 2) % mod; else if (n == 3) return 1ll * m * (m - 1) % mod * (m - 2) % mod * qpow(6) % mod; else return 1ll * m * (m - 1) % mod * (m - 2) % mod * (m - 3) % mod * qpow(24) % mod; }
void upd(int f[kMaxN][5], int sz, int cnt) { if (!cnt) return; int g[5] = {1, cnt, add(cnt, C(cnt, 2)), add(cnt, add(1ll * cnt * (cnt - 1) % mod, C(cnt, 3))), add(C(cnt, 4), add(1ll * cnt * C(cnt - 1, 2) % mod, add(C(cnt, 2), add(1ll * cnt * (cnt - 1) % mod, cnt))))}; for (int i = 3; ~i; --i) { for (int j = n; ~j; --j) { for (int k = 1; k <= 4 - i; ++k) if (j + k * sz <= n) inc(f[j + k * sz][i + k], 1ll * f[j][i] * g[k] % mod); } } }
void dickdreamer() { std::cin >> n >> mod; if (n == 1) return void(std::cout << "3\n"); g[0][0] = h[0][0] = 1; for (int i = 1; i <= n / 2; ++i) { for (int j = 0; j <= 3; ++j) inc(f[i][0], g[i - 1][j]); for (int j = 0; j <= 2; ++j) inc(f[i][1], g[i - 1][j]); for (int j = 0; j <= 2; ++j) inc(f[i][2], h[i - 1][j]);
upd(g, i, f[i][0]), upd(h, i, f[i][0]); upd(g, i, f[i][1]), upd(h, i, f[i][1]); upd(g, i, f[i][2]); } int ans = 0; for (int i = 0; i <= 4; ++i) inc(ans, g[n - 1][i]); for (int i = 0; i <= 3; ++i) inc(ans, g[n - 1][i]); for (int i = 0; i <= 3; ++i) inc(ans, h[n - 1][i]); if (~n & 1) { for (int i = 0; i <= 2; ++i) for (int j = i + 1; j <= 2; ++j) dec(ans, 1ll * f[n / 2][i] * f[n / 2][j] % mod); for (int i = 0; i <= 1; ++i) dec(ans, C(f[n / 2][i], 2)); } std::cout << ans << '\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; while (T--) dickdreamer(); return 0; }
|