結果
| 問題 | 
                            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;
}