結果
問題 | No.2504 NOT Path Painting |
ユーザー | suisen |
提出日時 | 2023-02-21 11:50:51 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
RE
|
実行時間 | - |
コード長 | 2,844 bytes |
コンパイル時間 | 1,508 ms |
コンパイル使用メモリ | 116,784 KB |
実行使用メモリ | 814,092 KB |
最終ジャッジ日時 | 2024-05-09 06:13:36 |
合計ジャッジ時間 | 3,711 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | RE | - |
testcase_01 | MLE | - |
testcase_02 | -- | - |
testcase_03 | -- | - |
testcase_04 | -- | - |
testcase_05 | -- | - |
testcase_06 | -- | - |
testcase_07 | -- | - |
testcase_08 | -- | - |
testcase_09 | -- | - |
testcase_10 | -- | - |
testcase_11 | -- | - |
testcase_12 | -- | - |
testcase_13 | -- | - |
testcase_14 | -- | - |
testcase_15 | -- | - |
testcase_16 | -- | - |
testcase_17 | -- | - |
testcase_18 | -- | - |
testcase_19 | -- | - |
testcase_20 | -- | - |
ソースコード
#include <deque> #include <iostream> #include <tuple> #include <vector> #include <atcoder/modint> using mint = atcoder::modint998244353; int edge_num(int n) { return (n * (n + 1)) >> 1; } auto find_path_on_tree(const std::vector<std::vector<int>> &g, int u, int v) { std::vector<int> res; auto dfs = [&](auto dfs, int cur, int par) -> bool { res.push_back(cur); if (cur == v) return true; for (int nxt : g[cur]) if (nxt != par and dfs(dfs, nxt, cur)) return true; res.pop_back(); return false; }; dfs(dfs, u, -1); return res; } #include <algorithm> #include <map> int main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); int n; std::cin >> n; std::vector<std::vector<int>> g(n); for (int i = 0; i < n - 1; ++i) { int u, v; std::cin >> u >> v; --u, --v; g[u].push_back(v); g[v].push_back(u); } const int m = edge_num(n); const mint inv_m = mint(m).inv(); std::map<std::pair<int, int>, std::vector<int>> paths; std::map<std::pair<int, int>, std::vector<int>> compl_paths; std::map<std::vector<int>, std::pair<int, int>> rev_paths; for (int x = 0; x < n; ++x) for (int y = 0; y <= x; ++y) { std::vector<int> path = find_path_on_tree(g, x, y); std::sort(path.begin(), path.end()); std::vector<int> compl_path; for (int i = 0, j = 0; i < n; ++i) { if (j < int(path.size()) and path[j] == i) { ++j; continue; } compl_path.push_back(i); } paths[std::make_pair(x, y)] = path; rev_paths[path] = std::make_pair(x, y); compl_paths[std::make_pair(x, y)] = compl_path; } std::map<std::pair<int, int>, mint> dp; auto rec = [&](auto rec, int x, int y) -> mint { if (auto it = dp.find(std::make_pair(x, y)); it != dp.end()) { return it->second; } mint a = 1, b = 1; std::vector<int> path = paths[std::make_pair(x, y)]; for (const auto &[_, compl_path] : compl_paths) { std::vector<int> next_path; std::set_difference(path.begin(), path.end(), compl_path.begin(), compl_path.end(), std::back_inserter(next_path)); if (next_path.size()) { if (next_path.size() == path.size()) { a -= inv_m; } else { auto [nx, ny] = rev_paths[next_path]; b += inv_m * rec(rec, nx, ny); } } } return dp[std::make_pair(x, y)] = b * a.inv(); }; mint ans = 1; for (int x = 0; x < n; ++x) for (int y = 0; y <= x; ++y) { ans += rec(rec, x, y) * inv_m; } std::cout << ans.val() << std::endl; return 0; }