如题。样例可以过。
#include<algorithm>
#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
const int maxn=1e5+2;
int n,a[maxn],sz[maxn],dep[maxn],dfn[maxn],cnt=0,son[maxn],tp[maxn],fa[maxn];
struct edge{
int u,v,w;
}e[maxn];
vector<int> g[maxn];
void predfs(int u,int f){
sz[u]=1;
for(int i=0;i<g[u].size();++i){
int v=g[u][i];
if(v==f) continue;
dep[v]=dep[u]+1;
fa[v]=u;
predfs(v,u);
sz[u]+=sz[v];
if(sz[son[u]]<sz[v]) son[u]=v;
}
return ;
}
void work(int u,int t){
dfn[u]=++cnt;
tp[u]=t;
if(!son[u]) return ;
work(son[u],t);
for(int i=0;i<g[u].size();++i){
int v=g[u][i];
if(v==fa[u]||v==son[u]) continue;
work(v,v);
}
return ;
}
int t[maxn*4],settag[maxn*4],plustag[maxn*4];
inline void pushdown(int o,int l,int r,int mid){
if(settag[o]>=0){
plustag[o*2]=0;
plustag[o*2+1]=0;
t[o*2]=settag[o];
t[o*2+1]=settag[o];
settag[o*2]=settag[o];
settag[o*2+1]=settag[o];
settag[o]=-1;
}
else if(plustag[o]>0){
plustag[o*2]+=plustag[o];
plustag[o*2+1]+=plustag[o];
t[o*2]+=plustag[o];
t[o*2+1]+=plustag[o];
plustag[o]=0;
}
return ;
}
void build(int o,int l,int r){
settag[o]=-1;
if(l==r){
t[o]=a[l];
return ;
}
int mid=l+(r-l)/2;
build(o*2,l,mid);
build(o*2+1,mid+1,r);
t[o]=max(t[o*2],t[o*2+1]);
}
void setupdate(int o,int l,int r,int x,int y,int v){
if(y<l||r<x) return ;
if(x<=l&&r<=y){
t[o]=settag[o]=v,plustag[o]=0;
return ;
}
int mid=l+(r-l)/2;
pushdown(o,l,r,mid);
setupdate(o*2,l,mid,x,y,v);
setupdate(o*2+1,mid+1,r,x,y,v);
t[o]=max(t[o*2],t[o*2+1]);
return ;
}
void plusupdate(int o,int l,int r,int x,int y,int v){
if(y<l||r<x) return ;
if(x<=l&&r<=y){
t[o]+=v,plustag[o]+=v;
return ;
}
int mid=l+(r-l)/2;
pushdown(o,l,r,mid);
plusupdate(o*2,l,mid,x,y,v);
plusupdate(o*2+1,mid+1,r,x,y,v);
t[o]=max(t[o*2],t[o*2+1]);
return ;
}
int query(int o,int l,int r,int x,int y){
if(y<l||r<x) return 0;
if(x<=l&&r<=y) return t[o];
int mid=l+(r-l)/2;
pushdown(o,l,r,mid);
return max(query(o*2,l,mid,x,y),query(o*2+1,mid+1,r,x,y));
}
int main(){
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
cin>>n;
for(int i=1;i<n;++i){
cin>>e[i].u>>e[i].v>>e[i].w;
g[e[i].u].push_back(e[i].v);
g[e[i].v].push_back(e[i].u);
}
predfs(1,0);
work(1,1);
for(int i=1;i<n;++i){
if(fa[e[i].u]==e[i].v) swap(e[i].u,e[i].v);
a[dfn[e[i].v]]=e[i].w;
}
build(1,1,n);
string opt;
while(cin>>opt){
if(opt=="Stop") break;
if(opt=="Change"){
int k,w;
cin>>k>>w;
setupdate(1,1,n,dfn[e[k].v],dfn[e[k].v],w);
}
else if(opt=="Cover"){
int u,v,w;
cin>>u>>v>>w;
while(tp[u]!=tp[v]){
if(dep[tp[u]]<dep[tp[v]]) swap(u,v);
setupdate(1,1,n,dfn[tp[u]],dfn[u],w);
u=fa[tp[u]];
}
if(dep[u]>dep[v]) swap(u,v);
setupdate(1,1,n,dfn[u]+1,dfn[v],w);
}
else if(opt=="Add"){
int u,v,w;
cin>>u>>v>>w;
while(tp[u]!=tp[v]){
if(dep[tp[u]]<dep[tp[v]]) swap(u,v);
plusupdate(1,1,n,dfn[tp[u]],dfn[u],w);
u=fa[tp[u]];
}
if(dep[u]>dep[v]) swap(u,v);
plusupdate(1,1,n,dfn[u]+1,dfn[v],w);
}
else {
int u,v,res=0;
cin>>u>>v;
while(tp[u]!=tp[v]){
if(dep[tp[u]]<dep[tp[v]]) swap(u,v);
res=max(res,query(1,1,n,dfn[tp[u]],dfn[u]));
u=fa[tp[u]];
}
if(dep[u]>dep[v]) swap(u,v);
res=max(res,query(1,1,n,dfn[u]+1,dfn[v]));
cout<<res<<'\n';
}
}
return 0;
}