結果
問題 |
No.3055 Simple Chicken Game
|
ユーザー |
![]() |
提出日時 | 2025-02-02 23:59:35 |
言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 1,326 ms / 2,000 ms |
コード長 | 3,752 bytes |
コンパイル時間 | 2,823 ms |
コンパイル使用メモリ | 106,980 KB |
実行使用メモリ | 496,896 KB |
最終ジャッジ日時 | 2025-02-05 00:30:50 |
合計ジャッジ時間 | 10,509 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 30 |
ソースコード
#include <cassert> #include <iostream> #include <numeric> #include <vector> #include <atcoder/modint> // 解説通りに実装したもの int main () { using mint = atcoder::modint; constexpr int kMaxN = 3000, kMinP = 100000000, kMaxP = 1000000000; int n, P; std::cin >> n >> P; assert(1 <= n && n <= kMaxN); assert(kMinP <= P && P <= kMaxP); mint::set_mod(P); const mint inv2 = mint::raw(2).inv(), inv4 = inv2 * inv2; constexpr int kOffset = 1; std::vector a(n, std::vector(3, std::vector(3, mint()))); for (int j = -1; j <= 1; ++j) { a[0][j + 1][j + 1] = mint::raw(1); } std::vector b(n, std::vector(3, std::vector(3, mint()))); for (int i = 0; i < n - 1; ++i) { for (int d = -1; d <= 1; ++d) { for (int e = -1; e <= 1; ++e) { if (e > 0) { a[i + 1][d + kOffset][e - 1 + kOffset] += a[i][d + kOffset][e + kOffset]; b[i + 1][d + kOffset][e - 1 + kOffset] += b[i][d + kOffset][e + kOffset]; } else if (e < 0) { a[i + 1][d + kOffset][e + kOffset] += a[i][d + kOffset][e + kOffset] * inv2; b[i + 1][d + kOffset][e + kOffset] += b[i][d + kOffset][e + kOffset] * inv2 + a[i][d + kOffset][e + kOffset] * inv2; a[i + 1][d + kOffset][e + 1 + kOffset] += a[i][d + kOffset][e + kOffset] * inv2; b[i + 1][d + kOffset][e + 1 + kOffset] += b[i][d + kOffset][e + kOffset] * inv2; } else { a[i + 1][d + kOffset][e - 1 + kOffset] += a[i][d + kOffset][e + kOffset] * inv2; b[i + 1][d + kOffset][e - 1 + kOffset] += b[i][d + kOffset][e + kOffset] * inv2; a[i + 1][d + kOffset][e + kOffset] += a[i][d + kOffset][e + kOffset] * inv4; b[i + 1][d + kOffset][e + kOffset] += b[i][d + kOffset][e + kOffset] * inv4 + a[i][d + kOffset][e + kOffset] * inv4; a[i + 1][d + kOffset][e + 1 + kOffset] += a[i][d + kOffset][e + kOffset] * inv4; b[i + 1][d + kOffset][e + 1 + kOffset] += b[i][d + kOffset][e + kOffset] * inv4; } } } } std::vector h(n, std::vector(3, mint())); for (int k = 0; k < n; ++k) { for (int d = -1; d <= 1; ++d) { h[k][d + kOffset] = std::accumulate(b[k][d + kOffset].begin(), b[k][d + kOffset].end(), mint()); assert(h[k][d + kOffset] == mint::raw(k) / 3 - (mint::raw(1) / 3 + d) * (mint::raw(4).pow(k) - 1) / 3 / mint::raw(4).pow(k)); } } std::vector p(n, std::vector(n, std::vector(3, mint()))); p[0][0][0 + kOffset] = 1; for (int i = 0; i < n - 1; ++i) { for (int x = 0; x <= i; ++x) { for (int d = -1; d <= 1; ++d) { if (d > 0) { p[i + 1][x + 1][d - 1 + kOffset] += p[i][x][d + kOffset]; } else if (d < 0) { p[i + 1][x][d + kOffset] += p[i][x][d + kOffset] * inv2; p[i + 1][x][d + 1 + kOffset] += p[i][x][d + kOffset] * inv2; } else { p[i + 1][x + 1][d - 1 + kOffset] += p[i][x][d + kOffset] * inv2; p[i + 1][x][d + kOffset] += p[i][x][d + kOffset] * inv4; p[i + 1][x][d + 1 + kOffset] += p[i][x][d + kOffset] * inv4; } } } } for (int i = 0; i < n; ++i) { mint r = 1; for (int x = 0; x <= i; ++x) { for (int d = -1; d <= 1; ++d) { const int z = x + d, y = i - (x + z); if (d > 0) { r += p[i][x][d + kOffset] * (x + y + h[n - 1 - i][d - 1 + kOffset]); } else if (d < 0) { r += p[i][x][d + kOffset] * (mint::raw(y) * inv2 + (n - 1 - h[n - 1 - i][d + 1 + kOffset]) * inv2); } else { r += p[i][x][d + kOffset] * ((x + y + h[n - 1 - i][d - 1 + kOffset]) * inv2 + mint::raw(y) * inv4 + (n - 1 - h[n - 1 - i][d + 1 + kOffset]) * inv4); } } } std::cout << r.val() << " \n"[i + 1 == n]; } return 0; }