結果
問題 | No.898 tri-βutree |
ユーザー | risujiroh |
提出日時 | 2019-10-04 22:02:28 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 210 ms / 4,000 ms |
コード長 | 2,334 bytes |
コンパイル時間 | 2,373 ms |
コンパイル使用メモリ | 185,616 KB |
実行使用メモリ | 34,300 KB |
最終ジャッジ日時 | 2024-11-08 22:10:03 |
合計ジャッジ時間 | 7,014 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 90 ms
34,300 KB |
testcase_01 | AC | 2 ms
5,248 KB |
testcase_02 | AC | 2 ms
5,248 KB |
testcase_03 | AC | 2 ms
5,248 KB |
testcase_04 | AC | 2 ms
5,248 KB |
testcase_05 | AC | 2 ms
5,248 KB |
testcase_06 | AC | 2 ms
5,248 KB |
testcase_07 | AC | 187 ms
31,784 KB |
testcase_08 | AC | 185 ms
31,784 KB |
testcase_09 | AC | 183 ms
31,780 KB |
testcase_10 | AC | 183 ms
31,784 KB |
testcase_11 | AC | 189 ms
31,716 KB |
testcase_12 | AC | 184 ms
31,896 KB |
testcase_13 | AC | 192 ms
31,904 KB |
testcase_14 | AC | 187 ms
31,788 KB |
testcase_15 | AC | 184 ms
31,912 KB |
testcase_16 | AC | 183 ms
31,780 KB |
testcase_17 | AC | 182 ms
31,784 KB |
testcase_18 | AC | 187 ms
31,776 KB |
testcase_19 | AC | 201 ms
31,904 KB |
testcase_20 | AC | 199 ms
31,784 KB |
testcase_21 | AC | 210 ms
31,904 KB |
ソースコード
#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; lint res = 0; for (int i = 0; i < 3; ++i) { res += LCA::acc(x[i], x[(i + 1) % 3]); } cout << res / 2 << '\n'; } }