結果
| 問題 |
No.3055 Simple Chicken Game
|
| コンテスト | |
| ユーザー |
emthrm
|
| 提出日時 | 2025-02-02 23:57:20 |
| 言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 3,700 bytes |
| コンパイル時間 | 2,065 ms |
| コンパイル使用メモリ | 115,188 KB |
| 実行使用メモリ | 503,968 KB |
| 最終ジャッジ日時 | 2025-02-05 00:30:49 |
| 合計ジャッジ時間 | 22,529 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 25 TLE * 5 |
ソースコード
#include <cassert>
#include <iostream>
#include <numeric>
#include <vector>
#include <atcoder/modint>
// 解説通りに実装したもの。
// ただし前計算を怠っているため TLE になっている。
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);
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] / 2;
b[i + 1][d + kOffset][e + kOffset] += b[i][d + kOffset][e + kOffset] / 2 + a[i][d + kOffset][e + kOffset] / 2;
a[i + 1][d + kOffset][e + 1 + kOffset] += a[i][d + kOffset][e + kOffset] / 2;
b[i + 1][d + kOffset][e + 1 + kOffset] += b[i][d + kOffset][e + kOffset] / 2;
} else {
a[i + 1][d + kOffset][e - 1 + kOffset] += a[i][d + kOffset][e + kOffset] / 2;
b[i + 1][d + kOffset][e - 1 + kOffset] += b[i][d + kOffset][e + kOffset] / 2;
a[i + 1][d + kOffset][e + kOffset] += a[i][d + kOffset][e + kOffset] / 4;
b[i + 1][d + kOffset][e + kOffset] += b[i][d + kOffset][e + kOffset] / 4 + a[i][d + kOffset][e + kOffset] / 4;
a[i + 1][d + kOffset][e + 1 + kOffset] += a[i][d + kOffset][e + kOffset] / 4;
b[i + 1][d + kOffset][e + 1 + kOffset] += b[i][d + kOffset][e + kOffset] / 4;
}
}
}
}
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] / 2;
p[i + 1][x][d + 1 + kOffset] += p[i][x][d + kOffset] / 2;
} else {
p[i + 1][x + 1][d - 1 + kOffset] += p[i][x][d + kOffset] / 2;
p[i + 1][x][d + kOffset] += p[i][x][d + kOffset] / 4;
p[i + 1][x][d + 1 + kOffset] += p[i][x][d + kOffset] / 4;
}
}
}
}
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) / 2 + (n - 1 - h[n - 1 - i][d + 1 + kOffset]) / 2);
} else {
r += p[i][x][d + kOffset] * ((x + y + h[n - 1 - i][d - 1 + kOffset]) / 2 + mint::raw(y) / 4 + (n - 1 - h[n - 1 - i][d + 1 + kOffset]) / 4);
}
}
}
std::cout << r.val() << " \n"[i + 1 == n];
}
return 0;
}
emthrm