# SPOJ 375 树链剖分

//By SiriusRen
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 22222
char ch[11];
int n,cases,root,tree[N*4],xx,yy,ans;
int tot,first[N],next[N],v[N],w[N];
int cnt,top[N],deep[N],size[N],son[N],rec[N],f[N];
struct Edge{int from,to,weight;}edge[N];
w[tot]=z,v[tot]=y;
next[tot]=first[x],first[x]=tot++;
}
void dfs(int x,int fa){
size[x]=1;son[x]=0;
for(int i=first[x];~i;i=next[i]){
if(v[i]==fa)continue;
f[v[i]]=x;
deep[v[i]]=deep[x]+1;
dfs(v[i],x);
size[x]+=size[v[i]];
if(size[v[i]]>size[son[x]])son[x]=v[i];
}
}
void dfs2(int x,int fa,int tp){
rec[x]=++cnt;top[x]=tp;
if(son[x])dfs2(son[x],x,tp);
for(int i=first[x];~i;i=next[i])
if(v[i]!=son[x]&&v[i]!=fa)dfs2(v[i],x,v[i]);
}
void insert(int l,int r,int pos){
if(l==r){tree[pos]=yy;return;}
int mid=(l+r)>>1;
if(mid<xx)insert(mid+1,r,pos<<1|1);
else insert(l,mid,pos<<1);
tree[pos]=max(tree[pos<<1],tree[pos<<1|1]);
}
int query(int l,int r,int pos,int Left,int Right){
if(l>=Left&&r<=Right)return tree[pos];
int mid=(l+r)>>1;
if(mid<Left)return query(mid+1,r,pos<<1|1,Left,Right);
else if(mid>=Right)return query(l,mid,pos<<1,Left,Right);
else return max(query(l,mid,pos<<1,Left,Right),query(mid+1,r,pos<<1|1,Left,Right));
}
void find(){
int fx=top[xx],fy=top[yy];
while(fx!=fy){
if(deep[fx]<deep[fy])swap(xx,yy),swap(fx,fy);
ans=max(ans,query(1,n,1,rec[fx],rec[xx]));
xx=f[fx];fx=top[xx];
}
if(xx==yy)return;
if(deep[xx]>deep[yy])swap(xx,yy);
ans=max(ans,query(1,n,1,rec[son[xx]],rec[yy]));
}
int main(){
scanf("%d",&cases);
while(cases--){
memset(tree,0,sizeof(tree));
memset(size,0,sizeof(size));
memset(first,-1,sizeof(first));
scanf("%d",&n);
for(int i=1;i<n;i++){
scanf("%d%d%d",&edge[i].from,&edge[i].to,&edge[i].weight);
}
root=(n+1)>>1;
f[root]=deep[root]=cnt=tot=0;
dfs(root,root),dfs2(root,root,root);
for(int i=1;i<n;i++){
if(deep[edge[i].from]>deep[edge[i].to])swap(edge[i].from,edge[i].to);
xx=rec[edge[i].to],yy=edge[i].weight;
insert(1,cnt,1);
}
while(scanf("%s",ch)&&ch[0]!='D'){
scanf("%d%d",&xx,&yy);
if(ch[0]=='Q')ans=0,find(),printf("%d\n",ans);
else xx=rec[edge[xx].to],insert(1,n,1);
}
}
}


#### SPOJ QTree5 [树链剖分]

2017-07-08 10:45:53

#### SPOJ QTREE (树链剖分 基于边权)

2016-07-17 12:58:34

#### spoj GSS7(树链剖分 + 线段树区间合并)

2013-12-28 16:40:53

#### SPOJ 2666 QTREE4 - Query on a tree IV

2016-03-01 00:28:09

#### SPOJ 375 树链剖分学习

2015-09-01 23:07:56

#### spoj 375 树链剖分模板

2014-09-29 15:52:14

#### LCT spoj 375 树链剖分

2017-04-11 15:27:33

#### spoj 375 （树链剖分）

2013-07-21 14:14:23

#### 【转】SPOJ 375 树链剖分

2014-04-09 19:53:03

#### 树链剖分（SPOJ 375）

2017-01-15 20:21:31