結果
問題 | No.898 tri-βutree |
ユーザー | risujiroh |
提出日時 | 2019-10-04 21:49:51 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
WA
|
実行時間 | - |
コード長 | 2,398 bytes |
コンパイル時間 | 2,463 ms |
コンパイル使用メモリ | 189,232 KB |
実行使用メモリ | 34,304 KB |
最終ジャッジ日時 | 2024-10-03 07:26:58 |
合計ジャッジ時間 | 6,490 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 90 ms
34,304 KB |
testcase_01 | AC | 2 ms
6,820 KB |
testcase_02 | WA | - |
testcase_03 | WA | - |
testcase_04 | WA | - |
testcase_05 | WA | - |
testcase_06 | WA | - |
testcase_07 | WA | - |
testcase_08 | WA | - |
testcase_09 | WA | - |
testcase_10 | WA | - |
testcase_11 | WA | - |
testcase_12 | WA | - |
testcase_13 | WA | - |
testcase_14 | WA | - |
testcase_15 | WA | - |
testcase_16 | WA | - |
testcase_17 | WA | - |
testcase_18 | WA | - |
testcase_19 | WA | - |
testcase_20 | WA | - |
testcase_21 | WA | - |
ソースコード
#include <bits/stdc++.h> using namespace std; using lint = long long; template<class T = int> using V = vector<T>; template<class T = int> using VV = V< V<T> >; namespace LCA { using T = lint; struct Edge { int to; T w; }; T op(const T& x, const T& y) { return x + y; } constexpr T e = 0; V<> dep; VV<> par; VV<T> val; void init(const VV<Edge>& g, int r) { int n = g.size(); dep.resize(n); par.assign(__lg(2 * n - 1), V<>(n, -1)); val.assign(__lg(2 * n - 1), V<T>(n, e)); auto dfs = [&](const auto& dfs, int v, int p) -> void { for (const auto& e : g[v]) if (e.to != p) { dep[e.to] = dep[v] + 1; par[0][e.to] = v; val[0][e.to] = e.w; dfs(dfs, e.to, v); } }; dep[r] = 0; dfs(dfs, r, -1); for (int k = 1; k < (int) par.size(); ++k) { for (int v = 0; v < n; ++v) { if (par[k - 1][v] == -1) continue; par[k][v] = par[k - 1][par[k - 1][v]]; val[k][v] = op(val[k - 1][v], val[k - 1][par[k - 1][v]]); } } } int get_par(int v, int h) { for (int k = 0; h > 0; h >>= 1, ++k) { if (v == -1) break; if (h & 1) v = par[k][v]; } return v; } int lca(int u, int v) { if (dep[u] > dep[v]) swap(u, v); v = get_par(v, dep[v] - dep[u]); if (u == v) return u; for (int k = par.size() - 1; k >= 0; --k) { if (par[k][u] != par[k][v]) { u = par[k][u]; v = par[k][v]; } } return par[0][u]; } T get_val(int v, int h) { T res = e; for (int k = 0; h > 0; h >>= 1, ++k) { if (v == -1) break; if (h & 1) { res = op(res, val[k][v]); v = par[k][v]; } } return res; } T acc(int u, int v) { int a = lca(u, v); return op(get_val(v, dep[v] - dep[a]), get_val(u, dep[u] - dep[a])); } } int main() { cin.tie(nullptr); ios::sync_with_stdio(false); int n; cin >> n; VV<LCA::Edge> g(n); for (int _ = 0; _ < n - 1; ++_) { int u, v, w; cin >> u >> v >> w; g[u].emplace_back(LCA::Edge{v, w}); g[v].emplace_back(LCA::Edge{u, w}); } LCA::init(g, 0); int q; cin >> q; while (q--) { V<> x(3); for (auto&& e : x) cin >> e; sort(begin(x), end(x), [&](int u, int v) { return LCA::dep[u] < LCA::dep[v]; }); lint res = LCA::acc(x[1], x[2]); res += LCA::acc(x[0], LCA::lca(x[1], x[2])); cout << res << '\n'; } }