結果
問題 |
No.3055 Simple Chicken Game
|
ユーザー |
|
提出日時 | 2025-01-18 16:10:41 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
TLE
|
実行時間 | - |
コード長 | 4,046 bytes |
コンパイル時間 | 2,804 ms |
コンパイル使用メモリ | 112,548 KB |
実行使用メモリ | 20,864 KB |
最終ジャッジ日時 | 2025-02-05 00:27:45 |
合計ジャッジ時間 | 11,289 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 17 RE * 12 TLE * 1 |
ソースコード
// naive #include <array> #include <cassert> #include <iostream> #include <vector> #include <atcoder/modint> using mint = atcoder::modint; #include <map> #include <tuple> struct S { double p; mint mp; S() : S(0) {} template <typename T> S(const T& x) : S(x, x) {} S(double p, mint mp) : p(p), mp(mp) {} friend S operator+(const S& a, const S& b) { return { a.p + b.p, a.mp + b.mp }; } friend S operator-(const S& a, const S& b) { return { a.p - b.p, a.mp - b.mp }; } friend S operator*(const S& a, const S& b) { return { a.p * b.p, a.mp * b.mp }; } friend S operator/(const S& a, const S& b) { return { a.p / b.p, a.mp / b.mp }; } }; int main() { int n, mod; std::cin >> n >> mod; mint::set_mod(mod); assert(n <= 20); std::map<std::tuple<int, int, int, int>, int> ops; std::vector<std::map<std::tuple<int, int, int, int, int, int, int, int>, S>> memo(n); for (int i = n - 1; i >= 0; --i) { for (int a = 0; a <= i; ++a) for (int b = 0; a + b <= i; ++b) { int c = i - a - b; auto dfs = [&](auto dfs, int j, int x, int y, int z, int v) -> S { std::tuple key{ j, a, b, c, x, y, z, v }; if (memo[i].count(key)) { return memo[i][key]; } if (j == n) { if (v == 0) { return memo[i][key] = y + z + a; } else if (v == 1) { return memo[i][key] = b; } else { return memo[i][key] = y + c; } } else { std::tuple op_key{ j, x + (v == 0), y + (v == 1), z + (v == 2) }; assert(ops.count(op_key)); int op = ops[op_key]; if (op == 0) { return memo[i][key] = dfs(dfs, j + 1, x, y, z + 1, v); } else if (op == 1) { return memo[i][key] = (dfs(dfs, j + 1, x + 1, y, z, v) + dfs(dfs, j + 1, x, y + 1, z, v)) / 2; } else { return memo[i][key] = (dfs(dfs, j + 1, x, y, z + 1, v) + (dfs(dfs, j + 1, x + 1, y, z, v) + dfs(dfs, j + 1, x, y + 1, z, v)) / 2) / 2; } } }; S v0 = dfs(dfs, i + 1, a, b, c, 2); S v1 = (dfs(dfs, i + 1, a, b, c, 0) + dfs(dfs, i + 1, a, b, c, 1)) / 2; if (std::abs(v0.p - v1.p) < 1e-6 and v0.mp == v1.mp) { assert(a == c); // ! ops[{i, a, b, c}] = 2; } else if (v0.p > v1.p) { assert(a < c); // ! ops[{i, a, b, c}] = 1; } else { assert(a > c); // ! ops[{i, a, b, c}] = 0; } } } std::vector<mint> R(n, 1); auto dfs = [&](auto dfs, int i, int x, int y, int z, mint p) -> void { if (i == n) return; std::tuple key{ i, x, y, z }; int op = ops[{i, x, y, z}]; if (op == 0) { R[i] += p * memo[i][{i + 1, x, y, z, x, y, z, 2}].mp; dfs(dfs, i + 1, x, y, z + 1, p); } else if (op == 1) { p /= 2; R[i] += p * memo[i][{i + 1, x, y, z, x, y, z, 0}].mp; R[i] += p * memo[i][{i + 1, x, y, z, x, y, z, 1}].mp; dfs(dfs, i + 1, x + 1, y, z, p); dfs(dfs, i + 1, x, y + 1, z, p); } else { p /= 2; R[i] += p * memo[i][{i + 1, x, y, z, x, y, z, 2}].mp; dfs(dfs, i + 1, x, y, z + 1, p); p /= 2; R[i] += p * memo[i][{i + 1, x, y, z, x, y, z, 0}].mp; R[i] += p * memo[i][{i + 1, x, y, z, x, y, z, 1}].mp; dfs(dfs, i + 1, x + 1, y, z, p); dfs(dfs, i + 1, x, y + 1, z, p); } }; dfs(dfs, 0, 0, 0, 0, 1); for (int i = 0; i < n; ++i) { if (i) std::cout << ' '; std::cout << R[i].val(); } std::cout << std::endl; }