SHOW:
|
|
- or go back to the newest paste.
1 | # include <iostream> | |
2 | # include <fstream> | |
3 | # include <sstream> | |
4 | # include <algorithm> | |
5 | # include <numeric> | |
6 | # include <cstdio> | |
7 | # include <cmath> | |
8 | # include <cstdlib> | |
9 | # include <cstring> | |
10 | # include <vector> | |
11 | # include <list> | |
12 | # include <set> | |
13 | # include <map> | |
14 | # include <iomanip> | |
15 | # include <stack> | |
16 | # include <queue> | |
17 | # include <cctype> | |
18 | # include <climits> | |
19 | # include <assert.h> | |
20 | ||
21 | using namespace std; | |
22 | ||
23 | //conversion | |
24 | //------------------------------------------ | |
25 | inline int toInt(string s) {int v; istringstream sin(s);sin>>v;return v;} | |
26 | template<class T> inline string toString(T x) {ostringstream sout;sout<<x;return sout.str();} | |
27 | ||
28 | typedef long long LL; | |
29 | typedef unsigned long long ULL; | |
30 | typedef vector<int> VI; | |
31 | typedef vector<VI> VVI; | |
32 | typedef vector<LL> VLL; | |
33 | typedef pair<int,int> PII; | |
34 | typedef pair<int, PII> TIII; | |
35 | typedef vector<PII> VPII; | |
36 | typedef vector<double> VD; | |
37 | typedef pair<double,double> PDD; | |
38 | ||
39 | const int inf=1000000000; | |
40 | const LL INF=LL(inf)*inf; | |
41 | const double eps=1e-9; | |
42 | const double PI=2*acos(0.0); | |
43 | ||
44 | #define GI ({int t;scanf("%d",&t);t;}) | |
45 | #define REP(i,a,b) for(int i=a;i<b;i++) | |
46 | #define foreach(c,itr) for(__typeof((c).begin()) itr=(c).begin();itr!=(c).end();itr++) | |
47 | #define ALL(v) (v).begin(),(v).end() | |
48 | #define RALL(a) (a).rbegin(), (a).rend() | |
49 | #define TR(i,x) for(typeof(x.begin()) i=x.begin();i!=x.end();i++) | |
50 | #define bit(n) (1<<(n)) | |
51 | #define bit64(n) ((LL(1))<<(n)) | |
52 | #define PB push_back | |
53 | #define SZ size() | |
54 | #define MP make_pair | |
55 | #define CL clear() | |
56 | #define fill(ar,val) memset((ar),(val), sizeof(ar)) | |
57 | #define MIN(a,b) {if((a)>(b)) (b);} | |
58 | #define MAX(a,b) {if((a)<(b)) (b);} | |
59 | #define EXIST(s,e) ((s).find(e)!=(s).end()) | |
60 | #define SORT(c) sort((c).begin(),(c).end()) | |
61 | #define MT(a,b,c) MP(a, MP(b, c)) | |
62 | #define sqr(x) ((x)*(x)) | |
63 | #define X first | |
64 | #define Y second | |
65 | #define REP(i,a,b) for(int i=a;i<b;i++) | |
66 | #define GI ({int t;scanf("%d",&t);t;}) | |
67 | #define DBPRINT cout << "HERE" << debugptr++ | |
68 | int debugptr = 0; | |
69 | ||
70 | //clock_t start=clock(); | |
71 | //fprintf(stderr,"time=%.3lfsec\n",0.001*(clock()-start)); | |
72 | ||
73 | #define MAXN 10003 | |
74 | #define MAXLN 14 | |
75 | #define root 1 | |
76 | ||
77 | int ptr; | |
78 | - | int par[MAXN][MAXLN]; |
78 | + | int par[MAXN]; |
79 | int chainNo; | |
80 | ||
81 | VI adj_list[MAXN]; | |
82 | VI costs[MAXN]; | |
83 | VI indexx[MAXN]; | |
84 | int L[MAXN]; | |
85 | int baseArray[MAXN]; | |
86 | int posInBase[MAXN]; | |
87 | int other_end[MAXN]; | |
88 | int subsize[MAXN]; | |
89 | int chain[MAXN]; | |
90 | int head_of_chain[MAXLN]; | |
91 | int pos_in_chain[MAXN]; | |
92 | int st[1 << (MAXLN + 1) + 5]; | |
93 | ||
94 | void construct(int i, int st_s, int st_e) { | |
95 | if (st_s == st_e) { | |
96 | st[i] = baseArray[st_s]; | |
97 | return; | |
98 | } | |
99 | int mid = (st_s+st_e)/2; | |
100 | construct(2*i+1, st_s, mid); | |
101 | construct(2*i+2, mid+1, st_e); | |
102 | st[i] = max(st[2*i+1],st[2*i+2]); | |
103 | } | |
104 | ||
105 | void update(int i, int st_s, int st_e, int s, int val) { | |
106 | if (st_s > s || st_e < s) return; | |
107 | if (st_s == st_e && st_s == s) { | |
108 | st[i] = val; | |
109 | return; | |
110 | } | |
111 | int mid = (st_s+st_e)/2; | |
112 | update(2*i+1, st_s, mid,s,val); | |
113 | update(2*i+2, mid+1, st_e,s,val); | |
114 | st[i] = max(st[2*i+1],st[2*i+2]); | |
115 | } | |
116 | ||
117 | int query(int i, int st_s, int st_e, int s, int e) { | |
118 | if (st_s > e || st_e < s) return 0; | |
119 | if (s <= st_s && st_e <= e) { | |
120 | return st[i]; | |
121 | } | |
122 | int mid = (st_s+st_e)/2; | |
123 | return max(query(2*i+1, st_s, mid,s, e),query(2*i+2, mid+1, st_e,s,e)); | |
124 | } | |
125 | ||
126 | void HLD(int curr, int prev, int cost) { | |
127 | if (head_of_chain[chainNo] == -1) { | |
128 | head_of_chain[chainNo] = curr; | |
129 | } | |
130 | ||
131 | chain[curr] = chainNo; | |
132 | posInBase[curr] = ptr; | |
133 | baseArray[ptr++] = cost; | |
134 | ||
135 | int sc = -1; | |
136 | int mss = 0; | |
137 | int nc = 0; | |
138 | REP(i,0,adj_list[curr].size()) { | |
139 | if (adj_list[curr][i] != prev && subsize[adj_list[curr][i]] > mss) { | |
140 | sc = adj_list[curr][i]; | |
141 | nc = costs[curr][i]; | |
142 | mss = subsize[adj_list[curr][i]]; | |
143 | } | |
144 | } | |
145 | ||
146 | if (sc != -1) { | |
147 | HLD(sc,curr,nc); | |
148 | } | |
149 | ||
150 | REP(i,0,adj_list[curr].size()) { | |
151 | if (adj_list[curr][i] != prev && adj_list[curr][i] != sc) { | |
152 | chainNo++; | |
153 | HLD(adj_list[curr][i], curr, costs[curr][i]); | |
154 | } | |
155 | } | |
156 | } | |
157 | ||
158 | void dfs(int r, int p, int d = 0) { | |
159 | - | par[r][0] = p; |
159 | + | par[r] = p; |
160 | subsize[r] = 1; | |
161 | L[r] = d; | |
162 | REP(i,0,adj_list[r].size()) { | |
163 | if (adj_list[r][i] != p) { | |
164 | other_end[indexx[r][i]] = adj_list[r][i]; | |
165 | dfs(adj_list[r][i],r,d+1); | |
166 | subsize[r] += subsize[adj_list[r][i]]; | |
167 | } | |
168 | } | |
169 | } | |
170 | ||
171 | void change(int a, int b) { | |
172 | int u = other_end[a]; | |
173 | update(0,0,ptr,posInBase[u],b); | |
174 | } | |
175 | ||
176 | - | int LCS(int u, int v) { |
176 | + | int LCA(int u, int v) { |
177 | while (chain[u] != chain[v]) { | |
178 | - | if (L[u] > L[v]) { |
178 | + | if (L[head_of_chain[chain[u]]] > L[head_of_chain[chain[v]]]) { |
179 | u = head_of_chain[chain[u]]; | |
180 | - | u = par[u][0]; |
180 | + | assert(u==1 || par[u] != -1); |
181 | u = par[u]; | |
182 | } | |
183 | else { | |
184 | - | v = par[v][0]; |
184 | + | |
185 | assert(par[v] != -1); | |
186 | v = par[v]; | |
187 | } | |
188 | } | |
189 | if (L[u] < L[v]) return u; | |
190 | return v; | |
191 | } | |
192 | ||
193 | int q(int a, int b) { | |
194 | if (a == b) return 0; | |
195 | int achain, bchain = chain[b], ans = -1; | |
196 | while(1) { | |
197 | achain = chain[a]; | |
198 | - | ans = max(ans,query(0,0,ptr,posInBase[a],posInBase[b])); |
198 | + | |
199 | if (a == b) break; | |
200 | ans = max(ans,query(0,0,ptr,posInBase[b],posInBase[a])); | |
201 | break; | |
202 | } | |
203 | - | a = par[a][0]; |
203 | + | |
204 | a = head_of_chain[achain]; | |
205 | a = par[a]; | |
206 | } | |
207 | return ans; | |
208 | - | int query(int a, int b) { |
208 | + | |
209 | - | int lcs = LCS(a, b); |
209 | + | |
210 | - | return max(q(lcs,a), q(lcs,b)); |
210 | + | int mquery(int a, int b) { |
211 | int lca = LCA(a, b); | |
212 | return max(q(a,lca), q(b,lca)); | |
213 | } | |
214 | ||
215 | int main(void) { | |
216 | ios_base::sync_with_stdio(0); | |
217 | #ifndef ONLINE_JUDGE | |
218 | freopen("i.txt","r",stdin); | |
219 | // freopen("o.txt","w",stdout); | |
220 | #endif | |
221 | int T; | |
222 | cin >> T; | |
223 | REP(i,0,T) { | |
224 | ptr = chainNo = 0; | |
225 | memset(head_of_chain, -1, sizeof head_of_chain); | |
226 | int N; cin >> N; | |
227 | REP(j,0,N+1) { | |
228 | adj_list[j].clear(); | |
229 | - | REP(k,0,MAXLN) par[j][k] = -1; |
229 | + | |
230 | indexx[j].clear(); | |
231 | par[j] = -1; | |
232 | } | |
233 | REP(j,1,N) { | |
234 | int a, b, c; | |
235 | cin >> a >> b >> c; | |
236 | adj_list[a].PB(b); | |
237 | adj_list[b].PB(a); | |
238 | costs[a].PB(c); | |
239 | costs[b].PB(c); | |
240 | indexx[a].PB(j); | |
241 | indexx[b].PB(j); | |
242 | } | |
243 | dfs(root,-1); | |
244 | HLD(root, -1, 0); | |
245 | construct(0,0,ptr); | |
246 | string s; int p1,p2; | |
247 | cin >> s; | |
248 | while(s[0] != 'D') { | |
249 | cin >> p1 >> p2; | |
250 | if (s[0] == 'C') { | |
251 | change(p1,p2); | |
252 | - | cout << query(p1,p2) << endl; |
252 | + | |
253 | else { | |
254 | cout << mquery(p1,p2) << endl; | |
255 | } | |
256 | cin >> s; | |
257 | } | |
258 | /* | |
259 | REP(l,0,2*N) { | |
260 | cout << st[l] << " "; | |
261 | } | |
262 | cout << "L " << LCA(4,5); | |
263 | cout << endl; | |
264 | */ | |
265 | } | |
266 | return 0; | |
267 | } |