|
| 1 | +#include <bits/stdc++.h> |
| 2 | +// http://www.spoj.com/problems/QTREE/ |
| 3 | +using namespace std; |
| 4 | +#define gc getchar_unlocked |
| 5 | +#define fo(i,n) for(i=0;i<n;i++) |
| 6 | +#define Fo(i,k,n) for(i=k;k<n?i<n:i>n;k<n?i+=1:i-=1) |
| 7 | +#define ll long long |
| 8 | +#define si(x) scanf("%d",&x) |
| 9 | +#define sl(x) scanf("%lld",&x) |
| 10 | +#define ss(s) scanf("%s",s) |
| 11 | +#define pi(x) printf("%d\n",x) |
| 12 | +#define pl(x) printf("%lld\n",x) |
| 13 | +#define ps(s) printf("%s\n",s) |
| 14 | +#define deb(x) cout << #x << "=" << x << endl |
| 15 | +#define deb2(x, y) cout << #x << "=" << x << "," << #y << "=" << y << endl |
| 16 | +#define pb push_back |
| 17 | +#define mp make_pair |
| 18 | +#define F first |
| 19 | +#define S second |
| 20 | +#define all(x) x.begin(), x.end() |
| 21 | +#define clr(x) memset(x, 0, sizeof(x)) |
| 22 | +#define sortall(x) sort(all(x)) |
| 23 | +#define tr(it, a) for(auto it = a.begin(); it != a.end(); it++) |
| 24 | +#define PI 3.1415926535897932384626 |
| 25 | +typedef pair<int, int> pii; |
| 26 | +typedef pair<ll, ll> pl; |
| 27 | +typedef vector<int> vi; |
| 28 | +typedef vector<ll> vl; |
| 29 | +typedef vector<pii> vpii; |
| 30 | +typedef vector<pl> vpl; |
| 31 | +typedef vector<vi> vvi; |
| 32 | +typedef vector<vl> vvl; |
| 33 | +int mpow(int base, int exp); |
| 34 | +void ipgraph(int m); |
| 35 | +void dfs(int u, int par); |
| 36 | +const int mod = 1000000007; |
| 37 | +const int N = 3e5, M = N; |
| 38 | +//======================= |
| 39 | +struct node{int v, w, i;}; |
| 40 | +vector<node> g[N]; |
| 41 | +int a[N], pos[N], arr[N]; |
| 42 | +int sz[N], lvl[N], rep[N]; |
| 43 | +int P[N][20], n; |
| 44 | +int chainNo, ptr; |
| 45 | +int chainOf[N], chainHead[N]; |
| 46 | +int tree[4*N]; |
| 47 | + |
| 48 | +void dfs(int u, int par){ |
| 49 | + sz[u] = 1; |
| 50 | + lvl[u] = 1+lvl[par]; |
| 51 | + P[u][0] = par; |
| 52 | + for(node to:g[u]){ |
| 53 | + int v = to.v; |
| 54 | + if (v == par) continue; |
| 55 | + rep[to.i] = v; |
| 56 | + dfs(v, u); |
| 57 | + sz[u] += sz[v]; |
| 58 | + } |
| 59 | +} |
| 60 | + |
| 61 | +int lca(int u, int v){ |
| 62 | + int i, lg; |
| 63 | + if (lvl[u] < lvl[v]) swap(u, v); |
| 64 | + for(lg = 0; (1<<lg) <= lvl[u]; lg++); |
| 65 | + lg--; |
| 66 | + for(i=lg; i>=0; i--){ |
| 67 | + if (lvl[u] - (1<<i) >= lvl[v]) |
| 68 | + u = P[u][i]; |
| 69 | + } |
| 70 | + if (u == v) return u; |
| 71 | + for(i=lg; i>=0; i--){ |
| 72 | + if (P[u][i] != -1 and P[u][i] != P[v][i]) |
| 73 | + u = P[u][i], v = P[v][i]; |
| 74 | + } |
| 75 | + return P[u][0]; |
| 76 | +} |
| 77 | +void init(){ |
| 78 | + int i, j; |
| 79 | + Fo(i, 0, n+1) g[i].clear(); |
| 80 | + ptr = 0, chainNo = 1; |
| 81 | + sz[0] = arr[0] = 0; |
| 82 | + lvl[0] = -1; |
| 83 | + Fo(i, 0, n+1) { |
| 84 | + chainHead[i] = -1; |
| 85 | + pos[i] = arr[i] = 0; |
| 86 | + Fo(j, 0, 20) P[i][j] = -1; |
| 87 | + } |
| 88 | +} |
| 89 | +int range_query(int rt, int lo, int hi, int x, int y){ |
| 90 | + if(lo == x and hi == y) return tree[rt]; |
| 91 | + int l = 2*rt, r = l+1, mid = (lo+hi)>>1; |
| 92 | + if(y <= mid) return range_query(l, lo, mid, x, y); |
| 93 | + if(x > mid) return range_query(r, mid+1, hi, x, y); |
| 94 | + return max(range_query(l, lo, mid, x, mid), range_query(r, mid+1, hi, mid+1, y)); |
| 95 | +} |
| 96 | +int query_up(int u, int v){ |
| 97 | + if(u == v) return 0; |
| 98 | + if(lvl[u] < lvl[v]) swap(u, v); |
| 99 | + int uchain, vchain = chainOf[v]; |
| 100 | + int ans = 0; |
| 101 | + while(1){ |
| 102 | + uchain = chainOf[u]; |
| 103 | + if(uchain == vchain){ |
| 104 | + if(u == v) return ans; |
| 105 | + ans = max(ans, range_query(1, 0, ptr, pos[v]+1, pos[u])); |
| 106 | + return ans; |
| 107 | + } |
| 108 | + ans = max(ans, range_query(1, 0, ptr, pos[chainHead[uchain]], pos[u])); |
| 109 | + u = chainHead[uchain]; |
| 110 | + u = P[u][0]; |
| 111 | + } |
| 112 | + return ans; |
| 113 | +} |
| 114 | +void hld(int u, int cost, int par){ |
| 115 | + if(chainHead[chainNo] == -1) |
| 116 | + chainHead[chainNo] = u; |
| 117 | + chainOf[u] = chainNo; |
| 118 | + pos[u] = ++ptr; |
| 119 | + arr[ptr] = cost; |
| 120 | + int sc = 0, w; |
| 121 | + for(node to: g[u]){ |
| 122 | + int v = to.v; |
| 123 | + if(v == par) continue; |
| 124 | + if(sz[sc] < sz[v])sc = v, w = to.w; |
| 125 | + } |
| 126 | + if(sc) hld(sc, w, u); |
| 127 | + for(node to: g[u]){ |
| 128 | + int v = to.v; |
| 129 | + if(v == par or v == sc) continue; |
| 130 | + chainNo++; |
| 131 | + hld(v, to.w, u); |
| 132 | + } |
| 133 | +} |
| 134 | +void build(int rt, int lo, int hi){ |
| 135 | + if(lo == hi){ |
| 136 | + tree[rt] = arr[lo]; |
| 137 | + return; |
| 138 | + } |
| 139 | + int l = 2*rt, r = l+1, mid = (lo+hi)>>1; |
| 140 | + build(l, lo, mid); |
| 141 | + build(r, mid+1, hi); |
| 142 | + tree[rt] = max(tree[l], tree[r]); |
| 143 | +} |
| 144 | +void update(int rt, int lo, int hi, int pos, int val){ |
| 145 | + if(lo == hi){ |
| 146 | + tree[rt] = val; |
| 147 | + return; |
| 148 | + } |
| 149 | + int l = 2*rt, r = l+1, mid = (lo+hi)>>1; |
| 150 | + if(pos<=mid) update(l, lo, mid, pos, val); |
| 151 | + else update(r, 1+mid, hi, pos, val); |
| 152 | + tree[rt] = max(tree[l], tree[r]); |
| 153 | +} |
| 154 | + |
| 155 | +int query(int u, int v){ |
| 156 | + int w = lca(u, v); |
| 157 | + int ans = max(query_up(u, w), query_up(v, w)); |
| 158 | + return ans; |
| 159 | +} |
| 160 | +void change(int i, int val){ |
| 161 | + int u = rep[i]; |
| 162 | + update(1, 0, ptr, pos[u], val); |
| 163 | +} |
| 164 | +void compute(){ |
| 165 | + int i, j; |
| 166 | + dfs(1, 0); |
| 167 | + for(i=1; i<20; i++){ |
| 168 | + Fo(j, 1, n+1) |
| 169 | + if (P[j][i-1] != -1) |
| 170 | + P[j][i] = P[P[j][i-1]][i-1]; |
| 171 | + } |
| 172 | + hld(1, 0, 0); |
| 173 | + //make segment tree now |
| 174 | + assert(ptr == n); |
| 175 | + build(1, 0, ptr); |
| 176 | +} |
| 177 | +void solve(){ |
| 178 | + int i; |
| 179 | + si(n); |
| 180 | + init(); |
| 181 | + int u, v, w; |
| 182 | + char s[10]; |
| 183 | + fo(i, n-1){ |
| 184 | + si(u); |
| 185 | + si(v); |
| 186 | + si(w); |
| 187 | + g[u].pb({v, w, i+1}); |
| 188 | + g[v].pb({u, w, i+1}); |
| 189 | + } |
| 190 | + compute(); |
| 191 | + ss(s); |
| 192 | + while(1){ |
| 193 | + if(s[0] == 'D') break; |
| 194 | + si(u); si(v); |
| 195 | + if(s[0] == 'C'){ |
| 196 | + change(u, v); |
| 197 | + } |
| 198 | + else{ |
| 199 | + pi(query(u, v)); |
| 200 | + } |
| 201 | + ss(s); |
| 202 | + } |
| 203 | +} |
| 204 | +int main() |
| 205 | +{ |
| 206 | + ios_base::sync_with_stdio(false); |
| 207 | + cin.tie(NULL); |
| 208 | + int i,k,j; |
| 209 | + int t; |
| 210 | + si(t); |
| 211 | + while(t--) solve(); |
| 212 | + return 0; |
| 213 | +} |
0 commit comments