結果
| 問題 | No.2504 NOT Path Painting |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2023-07-22 17:47:40 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 3,197 bytes |
| コンパイル時間 | 1,191 ms |
| コンパイル使用メモリ | 116,136 KB |
| 最終ジャッジ日時 | 2025-02-15 18:04:10 |
|
ジャッジサーバーID (参考情報) |
judge2 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 1 TLE * 1 -- * 19 |
ソースコード
// TLE 区間DP 愚直
#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);
auto solve = [&]{
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;
};
int t;
std::cin >> t;
while (t --> 0) {
solve();
}
return 0;
}