边权LCT...
一般用LCT搞边权有两种搞法,一种是类似树剖那样把边对应到点上,也就是除了根之外其他的节点都对应一条边,所以这样就不能换根,也就是不能进行树的分离和合并(好像如果LCT不能换根的话和树剖差不多了。。。);另一种是将每条边都当成一个点,然后将它的两个端点跟它连边,这样边权就转化成了点权,但是节点数多了一倍,可以实现各种操作。
#include<iostream>
#include<string>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#include<set>
#include<algorithm>
using namespace std;
#define LL long long
#define eps 1e-8
#define MP make_pair
#define N 20020
#define M 80020
#pragma comment(linker, "/STACK:1024000000,1024000000")
#define ls (i << 1)
#define rs (ls | 1)
#define md ((ll + rr) >> 1)
#define lson ll, md, ls
#define rson md + 1, rr, rs
#define mod 258280327
#define inf 0x3f3f3f3f
#define ULL unsigned long long
int readint() {
char c;
while((c = getchar()) && !(c >= '0' && c <= '9'));
int ret = c - '0';
while((c = getchar()) && c >= '0' && c <= '9')
ret = ret * 10 + c - '0';
return ret;
}
int n, m;
int ch[N][2], key[N], pre[N], rev[N];
bool rt[N];
int fst[N], nxt[M], vv[M], e;
int val[N];
int mx[N];
void init() {
for(int i = 1; i <= n + n - 1; ++i) {
rt[i] = 1;
fst[i] = -1;
ch[i][0] = ch[i][1] = 0;
pre[i] = 0;
val[i] = 0;
rev[i] = 0;
}
e = 0;
}
void add(int u, int v) {
vv[e] = v, nxt[e] = fst[u], fst[u] = e++;
}
void dfs(int u, int p) {
pre[u] = p;
mx[u] = val[u];
key[u] = val[u];
for(int i = fst[u]; ~i; i = nxt[i]) {
int v = vv[i];
if(v != p)
dfs(v, u);
}
}
void update_rev(int x) {
if(!x) return;
rev[x] ^= 1;
swap(ch[x][0], ch[x][1]);
}
void push_down(int x) {
if(rev[x]) {
update_rev(ch[x][0]);
update_rev(ch[x][1]);
rev[x] = 0;
}
}
void push_up(int x) {
mx[x] = key[x];
mx[x] = max(mx[x], mx[ch[x][0]]);
mx[x] = max(mx[x], mx[ch[x][1]]);
}
void rot(int x) {
int y = pre[x], d = ch[y][1] == x;
ch[y][d] = ch[x][!d];
pre[ch[x][!d]] = y;
pre[x] = pre[y];
pre[y] = x;
ch[x][!d] = y;
if(rt[y]) rt[y] = false, rt[x] = true;
else
ch[pre[x]][ch[pre[x]][1]==y] = x;
push_up(y);
}
void P(int x) {
if(!rt[x]) P(pre[x]);
push_down(x);
}
void splay(int x) {
P(x);
while(!rt[x]) {
int f = pre[x], ff = pre[f];
if(rt[f]) rot(x);
else if((ch[ff][1] == f) == (ch[f][1] == x))
rot(f), rot(x);
else
rot(x), rot(x);
}
push_up(x);
}
void Access(int x) {
int y = 0;
for(; x; y = x, x = pre[x]) {
splay(x);
rt[ch[x][1]] = true;
ch[x][1] = y;
rt[y] = false;
push_up(x);
}
}
void lca(int &u, int &v) {
Access(v), v = 0;
for(splay(u); pre[u]; v = u, u = pre[u], splay(u)) {
rt[ch[u][1]] = true;
ch[u][1] = v;
rt[v] = false;
push_up(u);
}
}
void make_root(int x) {
Access(x);
splay(x);
update_rev(x);
}
int query(int u, int v) {
/*
lca(u, v);
int ret = key[u];
ret = max(ret, mx[v]);
ret = max(ret, mx[ch[u][1]]);
*/
make_root(u);
Access(v);
splay(v);
return mx[v];
}
int main() {
int cas;
scanf("%d", &cas);
while(cas--) {
scanf("%d", &n);
init();
for(int i = 1; i < n; ++i) {
int u, v, c;
scanf("%d%d%d", &u, &v, &c);
add(i + n, u);
add(u, i + n);
add(i + n, v);
add(v, i + n);
val[i+n] = c;
}
dfs(1, 0);
char s[10];
while(1) {
scanf("%s", s);
if(s[0] == 'D') break;
int u, v;
scanf("%d%d", &u, &v);
if(s[0] == 'Q') {
make_root(u);
Access(v);
splay(v);
printf("%d\n", mx[v]);
}
else {
splay(u + n);
key[u+n] = v;
push_up(u + n);
}
}
}
return 0;
}