結果
問題 | No.898 tri-βutree |
ユーザー | theory_and_me |
提出日時 | 2019-10-04 23:42:30 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 514 ms / 4,000 ms |
コード長 | 3,987 bytes |
コンパイル時間 | 1,936 ms |
コンパイル使用メモリ | 177,272 KB |
実行使用メモリ | 36,480 KB |
最終ジャッジ日時 | 2024-11-08 22:30:53 |
合計ジャッジ時間 | 12,359 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 273 ms
36,480 KB |
testcase_01 | AC | 14 ms
17,024 KB |
testcase_02 | AC | 14 ms
17,024 KB |
testcase_03 | AC | 14 ms
17,024 KB |
testcase_04 | AC | 13 ms
17,024 KB |
testcase_05 | AC | 14 ms
17,024 KB |
testcase_06 | AC | 14 ms
17,024 KB |
testcase_07 | AC | 504 ms
29,696 KB |
testcase_08 | AC | 508 ms
29,696 KB |
testcase_09 | AC | 512 ms
29,696 KB |
testcase_10 | AC | 510 ms
29,568 KB |
testcase_11 | AC | 500 ms
29,696 KB |
testcase_12 | AC | 510 ms
29,696 KB |
testcase_13 | AC | 500 ms
29,696 KB |
testcase_14 | AC | 510 ms
29,568 KB |
testcase_15 | AC | 506 ms
29,824 KB |
testcase_16 | AC | 502 ms
29,696 KB |
testcase_17 | AC | 506 ms
29,696 KB |
testcase_18 | AC | 514 ms
29,696 KB |
testcase_19 | AC | 514 ms
29,696 KB |
testcase_20 | AC | 514 ms
29,696 KB |
testcase_21 | AC | 511 ms
29,696 KB |
ソースコード
#include <bits/stdc++.h> using namespace std; typedef unsigned long long ull; typedef long long ll; typedef pair<int, int> pii; typedef pair<ll, ll> pll; typedef pair<double, double> pdd; const ull mod = 1e9 + 7; #define REP(i,n) for(int i=0;i<(int)n;++i) //debug #define dump(x) cerr << #x << " = " << (x) << endl; #define debug(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ")" << " " << __FILE__ << endl; template<class S, class T> ostream& operator << (ostream& os, const pair<S, T> v){ os << "(" << v.first << ", " << v.second << ")"; return os; } template<class T> ostream& operator << (ostream& os, const vector<T> v){ for(int i = 0; i < v.size(); i++){if(i > 0){os << " ";} os << v[i];} return os; } template<class T> ostream& operator << (ostream& os, const vector<vector<T>> v){ for(int i = 0; i < v.size(); i++){if(i > 0){os << endl;} os << v[i];} return os; } // RMQ typedef ll Val; typedef pair<Val, Val> pVV; const Val INF_Val = LLONG_MAX; const int ME = 18; const int MN = 1<<ME; class RMQ_segtree{ public: pVV dat[2*MN-1]; RMQ_segtree(){ REP(i, 2*MN-1) dat[i] = make_pair(INF_Val, -1); } void update(int k, Val a){ //k番目の要素をaに変更 k += MN-1; dat[k] = make_pair(a, k-(MN-1)); while(k>0){ k = (k-1)/2; dat[k] = min(dat[2*k+1], dat[2*k+2]); } } pVV recursion(int a, int b, int k, int l, int r){ //最小値計算用の再帰関数 if(r<=a || b<=l) return make_pair(INF_Val, -1); if(a<=l && r<=b) return dat[k]; else{ pVV vl = recursion(a, b, 2*k+1, l, (l+r)/2); pVV vr = recursion(a, b, 2*k+2, (l+r)/2, r); return min(vl, vr); } } pVV minimum(int a, int b){ //区間[a, b)の最小値 return recursion(a, b, 0, 0, MN); } void print_val(int a, int b){ //区間[a, b)の値を出力 for(int i=a;i<b;i++) cout << dat[i+MN-1].first << endl; cout << endl; } }; // LCA const ll MAX_N = 101010; vector<ll> G[MAX_N]; ll vs[2*MAX_N-1]; ll depth[2*MAX_N-1]; ll id[MAX_N]; RMQ_segtree rmq; void dfs(ll now, ll par, ll d, ll &k){ id[now] = k; vs[k] = now; depth[k] = d; k++; REP(i, G[now].size()){ ll next = G[now][i]; if(next == par) continue; dfs(next, now, d+1, k); vs[k] = now; depth[k] = d; k++; } } void init(ll N){ ll k = 0; dfs(0, -1, 0, k); REP(i, 2*N-1) rmq.update(i, depth[i]); } ll lca(ll u, ll v){ ll mi = min(id[u], id[v]); ll ma = max(id[u], id[v]); return vs[rmq.minimum(mi, ma+1).second]; } struct Edge{ ll to, w; }; typedef vector<Edge> Edges; typedef vector<Edges> Graph; Graph GG(101010); vector<ll> wei(101010, 0); void dfs_wei(ll now, ll par, ll val){ wei[now] = val; REP(i, GG[now].size()){ ll next = GG[now][i].to; if(next == par) continue; dfs_wei(next, now, val+GG[now][i].w); } return; } int main(){ cin.tie(0); ios::sync_with_stdio(false); ll N; cin >> N; REP(i, N-1){ ll u, v, w; cin >> u >> v >> w; Edge e = {v, w}; Edge f = {u, w}; GG[u].push_back(e); GG[v].push_back(f); G[u].push_back(v); G[v].push_back(u); } dfs_wei(0, -1, 0); init(N); ll Q; cin >> Q; while(Q--){ ll x, y, z; cin >> x >> y >> z; ll res = 0; ll a = lca(y, z); ll b = lca(z, x); ll c = lca(x, y); res += (wei[y] + wei[z] - 2*wei[a]); res += (wei[z] + wei[x] - 2*wei[b]); res += (wei[x] + wei[y] - 2*wei[c]); /* ll d = lca(a, x); //printf("%lld, %lld, %lld, %lld\n", a, b, c, d); ll base = wei[d]; res += (wei[x] - base); res += (wei[y] - base); res += (wei[z] - base); res -= (wei[a] - base); res -= (wei[b] - base); res -= (wei[c] - base); */ cout << res/2 << endl; } /* REP(i, N){ cout << wei[i] << " "; } cout << endl; */ return 0; }