具体思路就是把 i 的父亲到 i 的边 看做 i 的点权,查询max时不查询根节点的max(因为根节点上面没有父亲.)
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=2e5+5, INF=1e9;
int fst[N<<1],nxt[N<<1],T[N<<1],W[N<<1],tot,wh[N];
void add_edge(int a,int b,int c,int i){
nxt[++tot]=fst[a];
fst[a]=tot;
T[tot]=b;
W[tot]=c;
wh[tot]=i;
}
int dep[N],f[N],siz[N],son[N], pos[N], beg[N];
void dfs(int p,int fp){
dep[p]=dep[fp]+1;
f[p]=fp;
siz[p]=1;
for(int i=fst[p];i;i=nxt[i]){
int j=T[i];
if(j==fp) continue;
dfs(j,p);
siz[p]+=siz[j];
if(siz[j]>siz[son[p]]) son[p]=j;
pos[wh[i]]=j;
beg[j]=W[i];
}
}
int rk[N],id[N],top[N],cnt;
void dfs2(int p,int fp){
top[p]=fp;
rk[++cnt]=p;
id[p]=cnt;
if(!son[p]) return;
dfs2(son[p],fp);
for(int i=fst[p];i;i=nxt[i]){
int j=T[i];
if(j!=f[p] && j!=son[p])
dfs2(j,j);
}
}
int n;
struct qwq{
int l,r;
int max;
int laz,fg;
qwq(){
l=r=0;
max=laz=0;
fg=-1;
}
void color1(int k){ //区间覆盖
max=k;
laz=0; fg=k;
}
void color2(int k){ //区间加
max+=k;
laz+=k;
}
}t[N<<2];
qwq operator+(const qwq &a,const qwq &b){
qwq c;
c.l=a.l; c.r=b.r;
c.max=max(a.max,b.max);
return c;
}
void build(int p,int l,int r){
if(l==r){
t[p].l=l; t[p].r=r;
t[p].max=beg[rk[l]];
return;
}
int mid=(l+r)>>1;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
t[p]=t[p<<1]+t[p<<1|1];
}
void pushdown(int p){
if(t[p].fg!=-1){
t[p<<1].color1(t[p].fg);
t[p<<1|1].color1(t[p].fg);
t[p].fg=-1;
}
if(t[p].laz){
t[p<<1].color2(t[p].laz);
t[p<<1|1].color2(t[p].laz);
t[p].laz=0;
}
}
void fugai(int p,int l,int r,int k){
if(t[p].l>r || t[p].r<l) return;
if(t[p].l>=l && t[p].r<=r){
t[p].color1(k);
return;
}
pushdown(p);
fugai(p<<1,l,r,k);
fugai(p<<1|1,l,r,k);
t[p]=t[p<<1]+t[p<<1|1];
}
void add(int p,int l,int r,int k){
if(t[p].l>r || t[p].r<l) return;
if(t[p].l>=l && t[p].r<=r){
t[p].color2(k);
return;
}
pushdown(p);
add(p<<1,l,r,k);
add(p<<1|1,l,r,k);
t[p]=t[p<<1]+t[p<<1|1];
}
int getmax(int p,int l,int r){
if(t[p].l>r || t[p].r<l) return 0;
if(t[p].l>=l && t[p].r<=r) return t[p].max;
pushdown(p);
int ans=max(getmax(p<<1,l,r),getmax(p<<1|1,l,r));
return ans;
}
void cz1(int k,int w){
fugai(1,id[pos[k]],id[pos[k]],w);
}
void cz2(int u,int v,int w){
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
fugai(1,id[top[u]],id[u],w);
u=f[top[u]];
}
if(id[u]>id[v]) swap(u,v);
fugai(1,id[u],id[v],w);
}
void cz3(int u,int v,int w){
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
add(1,id[top[u]],id[u],w);
u=f[top[u]];
}
if(id[u]>id[v]) swap(u,v);
add(1,id[u],id[v],w);
}
int cz4(int u,int v){
int ans=0;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
ans=max(ans,getmax(1,id[top[u]],id[u]));
u=f[top[u]];
}
if(id[u]>id[v]) swap(u,v);
if(id[u]!=1) ans=max(ans,getmax(1,id[u],id[v]));
else if(id[u]+1<=id[v])
ans=max(ans,getmax(1,id[u]+1,id[v]));
return ans;
}
int main(){
// freopen("1.in","r",stdin);
// freopen("qwq.out","w",stdout);
cin>>n;
int u,v,w;
for(int i=1;i<n;i++){
cin>>u>>v>>w;
add_edge(u,v,w,i);
add_edge(v,u,w,i);
}
dfs(1,0);
dfs2(1,1);
build(1,1,n);
char opt[15];
int k;
while(1){
cin>>opt;
if(opt[0]=='S') break;
else if(opt[0]=='C' && opt[1]=='h'){
cin>>k>>w;
cz1(k,w);
}
else if(opt[0]=='C' && opt[1]=='o'){
cin>>u>>v>>w;
cz2(u,v,w);
}
else if(opt[0]=='A'){
cin>>u>>v>>w;
cz3(u,v,w);
}
else{
cin>>u>>v;
cout<<cz4(u,v)<<"\n";
}
}
return 0;
}