题目大意:在一颗数上,每条边都有一个权值,让你修改其中一条边的值或者让你找出u,v两点之间权值最大的边。
树链剖分,第一个dfs求出每个点的siz(该点拥有的子节点数),son(其儿子节点中siz最大的那个),fa(该节点的父亲节点),dep(该节点所在层数)
第二个dfs就是为按重链为每一条边标记num下标和标记重链。
接着就是用线段树管理这些边,记得这些边是用num下标标记的,所以管理的时候就是管理id数组。
更新权值很简单,就是线段树点更新,找到要更新的边的下标然后更新就好了。
找u,v之间的最大权值边,不断的向上更替top,如果他们在一条链上那么直接就是线段树找区间最大值。
#include<bits/stdc++.h>
using namespace std;
#define maxn 100005
struct eo{
int x,y,val;
void read(){
scanf("%d%d%d",&x,&y,&val);
}
}e[maxn];
int siz[maxn],dep[maxn],fa[maxn],top[maxn];
int son[maxn],id[maxn],val[maxn],t[maxn<<2],num;
vector<int> v[maxn];
void dfs1(int u,int f,int de){
siz[u]=1;
fa[u]=f;
dep[u]=de;
son[u]=0;
int max_son=-1;
for(int i=0;i<v[u].size();i++){
int temp=v[u][i];
if(temp==f) continue;
dfs1(temp,u,de+1);
siz[u]+=siz[temp];
if(siz[temp]>max_son){
max_son=siz[temp];
son[u]=temp;
}
}
}
void dfs2(int u,int flag){
id[u]=++num;
top[u]=flag;
if(son[u]) dfs2(son[u],flag);
for(int i=0;i<v[u].size();i++){
int temp=v[u][i];
if(temp==son[u]||temp==fa[u]) continue;
dfs2(temp,temp);
}
}
void pushup(int rt){
t[rt]=max(t[rt<<1],t[rt<<1|1]);
return;
}
void bulid(int l,int r,int rt){
if(l==r){
t[rt]=val[l];
return;
}
int mid=(l+r)/2;
bulid(l,mid,rt<<1);
bulid(mid+1,r,rt<<1|1);
pushup(rt);
}
void update(int l,int r,int ad,int c,int rt){
if(l==ad&&ad==r){
t[rt]=c;
return;
}
int mid=(l+r)/2;
if(ad<=mid) update(l,mid,ad,c,rt<<1);
else update(mid+1,r,ad,c,rt<<1|1);
pushup(rt);
}
int query(int l,int r,int L,int R,int rt){
if(l>=L&&r<=R){
return t[rt];
}
int mid=(l+r)/2;
int ret=0;
if(L<=mid) ret=max(ret,query(l,mid,L,R,rt<<1));
if(R>mid) ret=max(ret,query(mid+1,r,L,R,rt<<1|1));
return ret;
}
int cha(int x,int y){
int topx=top[x],topy=top[y],ans=0;
while(topx!=topy){
if(dep[topx]<dep[topy]){
swap(x,y);
swap(topx,topy);
}
ans=max(ans,query(1,num,id[top[x]],id[x],1));
x=fa[topx];
topx=top[x];
}
if(x==y) return ans;
if(dep[x]>dep[y]) swap(x,y);
ans=max(ans,query(1,num,id[son[x]],id[y],1));
return ans;
}
int main(){
int t,n,a,b,c;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(int i=1;i<n;i++){
e[i].read();
v[e[i].x].push_back(e[i].y);
v[e[i].y].push_back(e[i].x);
}
num=0;
dfs1(1,0,1);
dfs2(1,1);
for(int i=1;i<n;i++){
if(dep[e[i].x]<dep[e[i].y]) swap(e[i].x,e[i].y);
val[id[e[i].x]]=e[i].val;
}
bulid(1,num,1);
char s[10];
int t1,t2;
while(~scanf("%s",&s)&&s[0]!='D'){
scanf("%d%d",&t1,&t2);
if(s[0]=='C'){
update(1,num,id[e[t1].x],t2,1);
}
else if(s[0]=='Q'){
printf("%d\n",cha(t1,t2));
}
}
for(int i=1;i<=n;i++){
v[i].clear();
}
}
return 0;
}