spoj Query on a tree
#include<iostream>
#include<cstring>
#include<cstdio>
#include<ostream>
#include<istream>
#include<algorithm>
#include<queue>
#include<string>
#include<cmath>
#include<set>
#include<map>
#include<stack>
#include<vector>
#define fi first
#define se second
#define pii pair<int,int>
#define inf (1<<30)
#define eps 1e-8
#define ll long long
using namespace std;
const int maxn=110005;
struct Edge
{
int from,to,w;
int next;
}edges[maxn];
int d[maxn][3];
int cnt;
int head[maxn];
int n;
int son[maxn],top[maxn],dep[maxn],fa[maxn],siz[maxn],id[maxn];
int sz;
int mx[maxn<<2];
void addEdge(int from,int to,int w)
{
edges[cnt].from=from;
edges[cnt].to=to;
edges[cnt].w=w;
edges[cnt].next=head[from];
head[from]=cnt++;
}
void dfs(int u,int f)
{
siz[u]=1;
son[u]=0;
for(int i=head[u];i!=-1;i=edges[i].next) {
if(edges[i].to==f)
continue;
int v=edges[i].to;
fa[v]=u;
dep[v]=dep[u]+1;
dfs(v,u);
if(siz[v]>siz[son[u]]) son[u]=v;
siz[u]+=siz[v];
}
}
void build(int u,int w)
{
id[u]=++sz;
top[u]=w;
if(son[u]) build(son[u],w);
for(int i=head[u];i!=-1;i=edges[i].next) {
int v=edges[i].to;
if(v==fa[u]) continue;
if(v!=son[u]) build(v,v);
}
}
void pushUp(int rt)
{
mx[rt]=max(mx[rt<<1],mx[rt<<1|1]);
}
void update(int l,int a,int L,int R,int rt)
{
if(l==L && R==l) {
mx[rt]=a;
return;
}
int m=(L+R)/2;
if(l<=m)
update(l,a,L,m,rt<<1);
else
update(l,a,m+1,R,rt<<1|1);
pushUp(rt);
}
void init()
{
fa[1]=0;
dep[1]=0;
dfs(1,0);
sz=0;
build(1,1);
memset(mx,0,sizeof(mx));
for(int i=0;i<n-1;i++) {
if(dep[d[i][0]]<dep[d[i][1]])
swap(d[i][0],d[i][1]);
update(id[d[i][0]],d[i][2],1,sz,1);
}
}
int query(int l,int r,int L,int R,int rt)
{
if(l<=L && r>=R)
return mx[rt];
int ans=0;
int m=(L+R)/2;
if(l<=m)
ans=max(ans,query(l,r,L,m,rt<<1));
if(r>m)
ans=max(ans,query(l,r,m+1,R,rt<<1|1));
return ans;
}
int Max(int a,int b)
{
int f1=top[a],f2=top[b];
int tmp=0;
while(f1!=f2) {
if(dep[f1]<dep[f2]) {
swap(f1,f2);
swap(a,b);
}
tmp=max(tmp,query(id[f1],id[a],1,sz,1));
a=fa[f1]; f1=top[a];
}
if(a==b) return tmp;
if(dep[a]>dep[b]) swap(a,b);
tmp=max(tmp,query(id[son[a]],id[b],1,sz,1));
return tmp;
}
int main()
{
int a,b,c;
char str[10];
int t;
scanf("%d",&t);
while(t--) {
memset(head,-1,sizeof(head));
cnt=0;
scanf("%d",&n);
for(int i=0;i<n-1;i++) {
scanf("%d%d%d",&a,&b,&c);
d[i][0]=a,d[i][1]=b,d[i][2]=c;
addEdge(a,b,c);
addEdge(b,a,c);
}
init();
while(~scanf("%s",str)) {
if(str[0]=='D') break;
if(str[0]=='Q') {
scanf("%d%d",&a,&b);
printf("%d\n",Max(a,b));
}
else {
scanf("%d%d",&a,&b);
update(id[d[a-1][0]],b,1,sz,1);
}
}
}
return 0;
}