結果
問題 | No.898 tri-βutree |
ユーザー | ぷら |
提出日時 | 2022-05-06 16:42:32 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 262 ms / 4,000 ms |
コード長 | 3,992 bytes |
コンパイル時間 | 2,763 ms |
コンパイル使用メモリ | 228,044 KB |
実行使用メモリ | 23,168 KB |
最終ジャッジ日時 | 2024-07-05 18:19:42 |
合計ジャッジ時間 | 10,140 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 101 ms
23,168 KB |
testcase_01 | AC | 2 ms
5,376 KB |
testcase_02 | AC | 2 ms
5,376 KB |
testcase_03 | AC | 2 ms
5,376 KB |
testcase_04 | AC | 2 ms
5,376 KB |
testcase_05 | AC | 2 ms
5,376 KB |
testcase_06 | AC | 2 ms
5,376 KB |
testcase_07 | AC | 248 ms
18,304 KB |
testcase_08 | AC | 256 ms
18,304 KB |
testcase_09 | AC | 253 ms
18,432 KB |
testcase_10 | AC | 254 ms
18,304 KB |
testcase_11 | AC | 249 ms
18,304 KB |
testcase_12 | AC | 252 ms
18,304 KB |
testcase_13 | AC | 249 ms
18,432 KB |
testcase_14 | AC | 250 ms
18,304 KB |
testcase_15 | AC | 255 ms
18,304 KB |
testcase_16 | AC | 254 ms
18,432 KB |
testcase_17 | AC | 262 ms
18,304 KB |
testcase_18 | AC | 261 ms
18,432 KB |
testcase_19 | AC | 256 ms
18,304 KB |
testcase_20 | AC | 259 ms
18,304 KB |
testcase_21 | AC | 261 ms
18,304 KB |
ソースコード
#include <bits/stdc++.h> using namespace std; template <typename T> struct BinaryIndexedTree { int N; vector<T>bit; BinaryIndexedTree(){} BinaryIndexedTree(int x) { N = x; bit.resize(x+1); } void add(int x,T y) { while(x <= N) { bit[x] += y; x += x&-x; } } T sum(int x) { T res = 0; while(x) { res += bit[x]; x -= x&-x; } return res; } inline T sum(int l, int r) {//[l,r] return sum(r)-sum(l-1); } inline T operator[](int k) { return sum(k)-sum(k-1); } }; struct HLD { vector<int>p,sz,in,nxt; BinaryIndexedTree<long long> bit; void dfs1(vector<vector<int>>&c,int v = 0) { sz[v] = 1; for(int &w:c[v]) { dfs1(c,w); sz[v] += sz[w]; if(sz[w] > sz[c[v][0]]) { swap(w,c[v][0]); } } } void dfs2(vector<vector<int>>&c,int &t,int v = 0) { in[v] = t; t++; for(int w:c[v]) { if(w == c[v][0]) { nxt[w] = nxt[v]; } else { nxt[w] = w; } dfs2(c,t,w); } } HLD(vector<long long>&A,vector<int>&p,vector<vector<int>>&c):p(p) { int N = A.size(); sz.resize(N,0); dfs1(c); in.resize(N,0); nxt.resize(N,0); int t = 0; dfs2(c,t); vector<long long>tmp(N); for(int i = 0; i < N; i++) { tmp[in[i]] = A[i]; } BinaryIndexedTree<long long>init(tmp.size()); for(int i = 0; i < tmp.size(); i++) { init.add(i+1,tmp[i]); } bit = init; } int lca(int u,int v) { while(true) { if(in[u] > in[v]) { swap(u,v); } if(nxt[u] == nxt[v]) { return u; } v = p[nxt[v]]; } } void update(int v,long long x) { bit.add(in[v]+1,x); } long long query(int u,int v) { int w = lca(u,v); long long ans = 0; while(nxt[u] != nxt[w]) { ans += bit.sum(in[nxt[u]]+1,in[u]+1); u = p[nxt[u]]; } ans += bit.sum(in[w]+2,in[u]+1); while(nxt[v] != nxt[w]) { ans += bit.sum(in[nxt[v]]+1,in[v]+1); v = p[nxt[v]]; } ans += bit.sum(in[w]+2,in[v]+1); return ans; } }; int now = 0; int cnt[100100]; void dfs(int n,vector<vector<int>>&c) { cnt[n] = now; now++; for(int i:c[n]) { dfs(i,c); } } bool chmax(int &x,int y) { if(x < y) { x = y; return true; } return false; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int N; cin >> N; vector<vector<pair<int,int>>>ki(N); for(int i = 0; i < N-1; i++) { int u,v,w; cin >> u >> v >> w; ki[u].push_back({v,w}); ki[v].push_back({u,w}); } vector<int>p(N,-1); vector<vector<int>>c(N); queue<int>que; que.push(0); vector<long long>A(N); while (!que.empty()) { int x = que.front(); que.pop(); for(auto i:ki[x]) { if(i.first != 0 && p[i.first] == -1) { p[i.first] = x; c[x].push_back(i.first); que.push(i.first); A[i.first] = i.second; } } } HLD hld(A,p,c); dfs(0,c); int Q; cin >> Q; while (Q--) { int K = 3; vector<int>A(K); vector<pair<int,int>>tmp; for(int i = 0; i < K; i++) { cin >> A[i]; tmp.push_back({cnt[A[i]],A[i]}); } sort(tmp.begin(),tmp.end()); long long ans = 0; for(int i = 0; i < K; i++) { ans += hld.query(tmp[i].second,tmp[(i+1)%K].second); } cout << ans/2 << '\n'; } }