这是一道经典的树链剖分的题目。
它涉及了边的最大值查询。
题意:
给你n个点,有n-1条边,2个操作。
1.“QUERY”查询x,y之间边的最大值
2.“CHANGE”,将第x条边的权值该为y
3.以“DONE”结束
这将一个点来对应一条边。
这个巧妙之处自行体会。
这与点之间还是有差异;
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#define For(aa,bb,cc) for(int aa=bb;aa<=cc;++aa)
#define Set(aa,bb) memset(aa,bb,sizeof(aa))
#define begin Begin
#define to To
#define next Next
#define rank Rank
#define lr node<<1
#define rr node<<1|1
using namespace std;
const int maxn=10010<<2;
int n,sum;
int begin[maxn],to[maxn],w[maxn],next[maxn],e;
int tree[maxn],rank[maxn],top[maxn],dep[maxn],tid[maxn],son[maxn],size[maxn],fa[maxn],num[maxn];
struct md{
int m,d,z;
}a[maxn];
void add(int x,int y,int z){
to[++e]=y,next[e]=begin[x],begin[x]=e,w[e]=z;
}
void dfs1(int node,int father,int deep){
dep[node]=deep;
fa[node]=father;
size[node]=1;
for(int i=begin[node];i;i=next[i]){
int u=to[i];
if(u!=father){
dfs1(u,node,deep+1);
size[node]+=size[u];
if(son[node]==-1 || size[u]>size[son[node]]) son[node]=u;
}
}
return ;
}
void dfs2(int node,int high){
top[node]=high;
tid[node]=++sum;
rank[tid[node]]=node;
if(son[node]==-1) return ;
dfs2(son[node],high);
for(int i=begin[node];i;i=next[i]){
int u=to[i];
if(u!=fa[node] && u!=son[node]){
dfs2(u,u);
}
}
return ;
}
void push_up(int node){
tree[node]=max(tree[lr],tree[rr]);
}
void create_tree(int node,int l,int r){
if(l==r){
tree[node]=num[l];
//cout<<node<<": "<<l<<' '<<r<<' '<<tree[node]<<endl;
return ;
}
int mid=(l+r)>>1;
create_tree(lr,l,mid);
create_tree(rr,mid+1,r);
push_up(node);
//cout<<node<<": "<<l<<' '<<r<<' '<<tree[node]<<endl;
return ;
}
int query(int node,int l,int r,int be,int en){
if(be<=l && en>=r){
return tree[node];
}
int mid=(l+r)>>1;
if(en<=mid)return query(lr,l,mid,be,en);
if(be>mid) return query(rr,mid+1,r,be,en);
return max(query(lr,l,mid,be,mid),query(rr,mid+1,r,mid+1,en));
}
int ask(int x,int y){
int ans=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
ans=max(ans,query(1,1,n,tid[top[x]],tid[x]));
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
if(x!=y)ans=max(ans,query(1,1,n,tid[x]+1,tid[y]));
return ans;
}
void update(int node,int l,int r,int be,int ad){
if(l==r){
tree[node]=ad;
return ;
}
int mid=(l+r)>>1;
if(be<=mid) update(lr,l,mid,be,ad);
if(be>mid) update(rr,mid+1,r,be,ad);
push_up(node);
return ;
}
void change(int x,int y){
if(dep[a[x].m]>dep[a[x].d]){
update(1,1,n,tid[a[x].m],y);
}else{
update(1,1,n,tid[a[x].d],y);
}
return ;
}
void work(){
e=0,sum=0;
Set(begin,0),Set(son,-1);
scanf("%d",&n);
For(i,1,n-1){
scanf("%d%d%d",&a[i].m,&a[i].d,&a[i].z);
add(a[i].m,a[i].d,a[i].z);
add(a[i].d,a[i].m,a[i].z);
}
dfs1(1,0,0);
dfs2(1,1);
For(i,1,n-1){
if(dep[a[i].m]>dep[a[i].d]){
num[tid[a[i].m]]=a[i].z;
}else{
num[tid[a[i].d]]=a[i].z;
}
}
create_tree(1,1,n);
while(1){
char s[20];int x,y;
scanf("%s",s);
if(s[0]=='D') return;
scanf("%d%d",&x,&y);
if(s[0]=='Q'){
printf("%d\n",ask(x,y));
}else{
change(x,y);
}
}
}
int main(){
int _;
scanf("%d",&_);
while(_--) work();
return 0;
}