参考ACdream的
用深度较深的点表示边 故build过程为(1,2,n)
关于修改的关系
注解里还有些待解决的和深入理解的地方
#include <bits/stdc++.h>
#define N 10100
#define FREI freopen("in.txt","r",stdin)
#define Mem(a,b) memset(a,b,sizeof(a))
#define lson root<<1
#define rson root<<1|1
#define Mid int mid=(l+r)>>1
#define inf 0x3f3f3f3f
using namespace std;
int n,m,k,siz[N],fa[N],son[N],cnt,f[N],invf[N],dep[N],tp[N],sum[N<<2],ans,ecnt;
int wedge[N];
struct edge{
int v,cost,next;
};
edge e[N<<2];
struct E{
int u,v,cost;
};
E edg[N];
int head[N];
void add(int u,int v,int cost){
e[ecnt]=(edge){v,cost,head[u]};
head[u]=ecnt++;
}
void dfs1(int u,int father){
dep[u]=dep[father]+1;
fa[u]=father;
siz[u]++;
for(int i=head[u];~i;i=e[i].next){//auto 有问题??
int v=e[i].v;
if(v!=father){
dfs1(v,u);
siz[u]+=siz[v];
if(son[u]==-1||siz[son[u]]<siz[v])
son[u]=v;
}
}
}
void dfs2(int u,int top){
tp[u]=top;
f[u]=++cnt;//时间戳 映射
invf[f[u]]=u;//逆映射
if(son[u]==-1)//忘了判断条件
return ;
dfs2(son[u],top);
for(int i=head[u];~i;i=e[i].next){
int v=e[i].v;
if(v!=son[u]&&v!=fa[u]){
dfs2(v,v);
}
}
}
void push_up(int root,int l,int r){
sum[root]=max(sum[lson],sum[rson]);
}
void build(int root,int l,int r){
if(l==r){
sum[root]=wedge[l];
return ;
}
Mid;
build(lson,l,mid);
build(rson,mid+1,r);
push_up(root,l,r);
}
void update(int root,int l,int r,int ql,int qr,int val){
if(l>qr||r<ql)
return;
if(l>=ql&&r<=qr){
sum[root]=val;
return ;
}
Mid;
update(lson,l,mid,ql,qr,val);
update(rson,mid+1,r,ql,qr,val);
push_up(root,l,r);
}
void query(int root,int l,int r,int ql,int qr){
if(l>qr||r<ql)
return;
if(l>=ql&&r<=qr){
ans=max(ans,sum[root]);
return ;
}
Mid;
query(lson,l,mid,ql,qr);
query(rson,mid+1,r,ql,qr);
}
void change(int x,int y){
while(tp[x]!=tp[y]){
if(dep[tp[x]]<dep[tp[y]]) swap(x,y);
query(1,2,n,f[tp[x]],f[x]);//可以加上顶端上面的那条边!!
x=fa[tp[x]];
}
if(dep[x]>dep[y]) swap(x,y);
if(x!=y) query(1,2,n,f[x]+1,f[y]);
}
int main() {
//FREI;
int cas;
for(scanf("%d",&cas);cas--;){
Mem(head,-1);
Mem(dep,0);
Mem(siz,0);
Mem(son,-1);
ecnt=cnt=0;
scanf("%d",&n);
for(int i=1;i<n;i++){
int u,v,c;
scanf("%d%d%d",&u,&v,&c);
edg[i].u=u,edg[i].v=v,edg[i].cost=c;
add(u,v,c);
add(v,u,c);
}
dfs1(1,1);// 0 1有区别?????
dfs2(1,1);
for(int i=1;i<n;i++){
int u=edg[i].u,v=edg[i].v,c=edg[i].cost;
dep[u]>dep[v]?wedge[f[u]]=c:wedge[f[v]]=c;
}
build(1,2,n);
char s[10];
getchar();
while(1){
scanf("%s",s);
if(s[0]=='Q'){
int x,y;
scanf("%d%d",&x,&y);
ans=-inf;
change(x,y);
printf("%d\n",ans);
}
else if(s[0]=='C'){
int x,y;
scanf("%d%d",&x,&y);
int u=edg[x].u,v=edg[x].v;
int id=dep[u]>dep[v]?f[u]:f[v];
update(1,2,n,id,id,y);
}
else break;
}
}
}