SHOW:
|
|
- or go back to the newest paste.
1 | #include<bits/stdc++.h> | |
2 | using namespace std; | |
3 | ||
4 | const int sz = 10000; | |
5 | const int lgsz = 15; | |
6 | ||
7 | vector<int> g[sz]; | |
8 | ||
9 | struct segment_tree { | |
10 | vector<int> t; | |
11 | int n; | |
12 | segment_tree(int n) { | |
13 | this->n = n; | |
14 | t.assign(n * 4, 0); | |
15 | } | |
16 | void upd(int v, int tl, int tr, int i, int val) { | |
17 | if(tl + 1 == tr) { | |
18 | t[v] = val; | |
19 | } else { | |
20 | int tm = (tl + tr) / 2; | |
21 | if(i < tm) { | |
22 | upd(v * 2 + 1, tl, tm, i, val); | |
23 | } else { | |
24 | upd(v * 2 + 2, tm, tr, i, val); | |
25 | } | |
26 | t[v] = max(t[v * 2 + 1], t[v * 2 + 2]); | |
27 | } | |
28 | } | |
29 | int get(int v, int tl, int tr, int l, int r) { | |
30 | if(tl >= r || tr <= l) return 0; | |
31 | if(tl >= l && tr <= r) return t[v]; | |
32 | int tm = (tl + tr) / 2; | |
33 | return max( | |
34 | get(v * 2 + 1, tl, tm, l, r), | |
35 | get(v * 2 + 2, tm, tr, l, r) | |
36 | ); | |
37 | } | |
38 | }; | |
39 | ||
40 | ||
41 | int tsize[sz]; | |
42 | int par[sz][lgsz]; | |
43 | int depth[sz]; | |
44 | ||
45 | void dfs(int f, int p, int h = 0) { | |
46 | tsize[f] = 1; | |
47 | par[f][0] = p; | |
48 | depth[f] = h; | |
49 | for(int h=1;h<lgsz;h++) { | |
50 | par[f][h] = par[par[f][h-1]][h-1]; | |
51 | } | |
52 | for(int v : g[f]) { | |
53 | if(v != p) { | |
54 | dfs(v, f, h + 1); | |
55 | tsize[f] += tsize[v]; | |
56 | } | |
57 | } | |
58 | } | |
59 | ||
60 | void buildHLD(int f, int p, int c, vector<vector<int> > & hld) { | |
61 | bool used = false; | |
62 | for(int v : g[f]) { | |
63 | if(v == p) continue; | |
64 | if(tsize[v] > tsize[f] / 2) { | |
65 | used = true; | |
66 | if(c) { | |
67 | hld.back().push_back(v); | |
68 | buildHLD(v, f, 1, hld); | |
69 | } else { | |
70 | hld.push_back({f, v}); | |
71 | buildHLD(v, f, 1, hld); | |
72 | } | |
73 | break; | |
74 | } | |
75 | } | |
76 | if(!used) { | |
77 | hld.push_back({f}); | |
78 | } | |
79 | for(int v : g[f]) { | |
80 | if(v == p) continue; | |
81 | if(tsize[v] <= tsize[f] / 2) { | |
82 | buildHLD(v, f, 0, hld); | |
83 | } | |
84 | } | |
85 | } | |
86 | ||
87 | int inhld[sz]; | |
88 | int ind[sz]; | |
89 | ||
90 | int lca(int f, int t) { | |
91 | if(depth[f] < depth[t]) swap(f,t); | |
92 | for(int i=lgsz-1;i>=0;i--) { | |
93 | if(depth[par[f][i]] >= depth[t]) { | |
94 | f = par[f][i]; | |
95 | } | |
96 | } | |
97 | if(f == t) return f; | |
98 | for(int i=lgsz-1;par[f][0] != par[t][0];i--) { | |
99 | if(par[f][i] != par[t][i]) { | |
100 | f = par[f][i]; | |
101 | t = par[t][i]; | |
102 | } | |
103 | } | |
104 | return par[f][0]; | |
105 | } | |
106 | ||
107 | struct HLD { | |
108 | vector<int> head; | |
109 | vector<segment_tree> hld; | |
110 | int n; | |
111 | HLD(vector<vector<int> > & hways) { | |
112 | this -> n = hways.size(); | |
113 | for(int i=0;i<n;i++) { | |
114 | hld.emplace_back((int)hways[i].size()); | |
115 | head.push_back(hways[i][0]); | |
116 | } | |
117 | } | |
118 | void upd(int v, int value) { | |
119 | hld[inhld[v]].upd(0, 0, hld[inhld[v]].n, ind[v], value); | |
120 | } | |
121 | int get(int f, int t) { | |
122 | int u = lca(f, t); | |
123 | int ans = 0; | |
124 | while(inhld[f] != inhld[u]) { | |
125 | ans = max(ans, hld[inhld[f]].get(0, 0, hld[inhld[f]].n, 0, ind[f] + 1)); | |
126 | f = par[head[inhld[f]]][0]; | |
127 | } | |
128 | while(inhld[t] != inhld[u]) { | |
129 | ans = max(ans, hld[inhld[t]].get(0, 0, hld[inhld[t]].n, 0, ind[t] + 1)); | |
130 | t = par[head[inhld[t]]][0]; | |
131 | } | |
132 | if(depth[f] < depth[t]) swap(f, t); | |
133 | ans = max(ans, hld[inhld[f]].get(0, 0, hld[inhld[f]].n, ind[t] + 1, ind[f]+ 1)); | |
134 | return ans; | |
135 | } | |
136 | }; | |
137 | ||
138 | void solve() { | |
139 | int n; | |
140 | cin >> n; | |
141 | for(int i=0;i<n;i++) { g[i].clear(); } | |
142 | vector<pair<int,int> > edges; | |
143 | vector<int> w; | |
144 | for(int i=0;i<n - 1;i++) { | |
145 | int f, t, curw; | |
146 | cin >> f >> t >> curw; | |
147 | f--,t--; | |
148 | edges.push_back(make_pair(f,t)); | |
149 | g[f].push_back(t); | |
150 | g[t].push_back(f); | |
151 | w.push_back(curw); | |
152 | } | |
153 | dfs(0, 0); | |
154 | vector<int> etov(n - 1); | |
155 | for(int i=0;i<n-1;i++) { | |
156 | int f = edges[i].first; | |
157 | int t = edges[i].second; | |
158 | if(par[f][0] == t) { | |
159 | etov[i] = f; | |
160 | } else { | |
161 | etov[i] = t; | |
162 | } | |
163 | } | |
164 | vector<vector<int> > hways; | |
165 | buildHLD(0, 0, 0, hways); | |
166 | for(int i=0;i<hways.size();i++) { | |
167 | for(int j=0;j<hways[i].size();j++) { | |
168 | inhld[hways[i][j]] = i; | |
169 | ind[hways[i][j]] = j; | |
170 | } | |
171 | } | |
172 | HLD hld (hways); | |
173 | for(int i=0;i<n-1;i++) { | |
174 | hld.upd(etov[i], w[i]); | |
175 | } | |
176 | string t; | |
177 | cin >> t; | |
178 | while(t != "DONE") { | |
179 | if(t == "QUERY") { | |
180 | int u, v; | |
181 | cin >> u >> v; | |
182 | u--,v--; | |
183 | cout << hld.get(u, v) << "\n"; | |
184 | } else { | |
185 | int i, val; | |
186 | cin >> i >> val; | |
187 | i--; | |
188 | hld.upd(etov[i], val); | |
189 | } | |
190 | cin >> t; | |
191 | } | |
192 | } | |
193 | ||
194 | ||
195 | int main() { | |
196 | ios_base::sync_with_stdio(false); | |
197 | cin.tie(nullptr); | |
198 | int t; | |
199 | cin >> t; | |
200 | while(t--) { | |
201 | solve(); | |
202 | } | |
203 | return 0; | |
204 | } |