#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+5;
int n;
string op;//操作类型
int l,r,k;//rt
int u[N],v[N],w[N];
struct Edge
{
int v,w;
};
vector<Edge> edge[N];
int dfn[N],rk[N],fa[N],tot;
int siz[N]/*子树大小*/,son[N]/*重儿子*/;
int top[N];//链头
int deep[N];//深度
int tree[N<<2];
int cover[N<<2],add[N<<2];
void dfs1(int u,int f)
{
fa[u]=f;//父亲节点
dfn[u]=++tot;//dfs序
rk[tot]=u;
siz[u]=1;//子树大小初始化
deep[u]=deep[f]+1;//深度
for(auto i:edge[u])
{
int v=i.v;
if(v!=f)
{
dfs1(v,u);
if(siz[v]>siz[son[u]]) son[u]=v;//更新重儿子
siz[u]+=siz[v];//更新子树大小
}
}
}
void dfs2(int u,int head)//链头
{
top[u]=head;
for(auto i:edge[u])
{
int v=i.v;
if(v!=fa[u])
{
if(v==son[u])
dfs2(v,head);
else
dfs2(v,v);
}
}
}
int ls(int x){return x<<1;}
int rs(int x){return x<<1|1;}
void build(int s,int t,int p)
{
if(s==t)
{
cover[p]=-1;
return;
}
int mid=s+(t-s>>1);
build(s,mid,ls(p));
build(mid+1,t,rs(p));
cover[p]=-1;
}
void push_down(int p)
{
if(cover[p]!=-1)
{
cover[ls(p)]=cover[rs(p)]=cover[p];
tree[ls(p)]=tree[rs(p)]=cover[p];
add[ls(p)]=add[rs(p)]=0;
cover[p]=-1;
}
if(add[p])
{
add[ls(p)]+=add[p];
add[rs(p)]+=add[p];
tree[ls(p)]+=add[p];
tree[rs(p)]+=add[p];
add[p]=0;
}
}
void update(int l,int r,int k,int s,int t,int p)
{
if(l<=s and t<=r)
{
tree[p]+=k;
add[p]+=k;
return;
}
push_down(p);
int mid=s+(t-s>>1);
if(l<=mid) update(l,r,k,s,mid,ls(p));
if(mid+1<=r) update(l,r,k,mid+1,t,rs(p));
tree[p]=max(tree[ls(p)],tree[rs(p)]);
}//Add
void Cover(int l,int r,int k,int s,int t,int p)
{
if(l<=s and t<=r)
{
tree[p]=k;
add[p]=0;
cover[p]=k;
return;
}
push_down(p);
int mid=s+(t-s>>1);
if(l<=mid) Cover(l,r,k,s,mid,ls(p));
if(mid+1<=r) Cover(l,r,k,mid+1,t,rs(p));
tree[p]=max(tree[ls(p)],tree[rs(p)]);
}//Cover and Change
int query(int l,int r,int s,int t,int p)
{
if(l<=s and t<=r) return tree[p];
int ans=LLONG_MIN;
push_down(p);
int mid=s+(t-s>>1);
if(l<=mid) ans=query(l,r,s,mid,ls(p));
if(mid+1<=r) ans=max(ans,query(l,r,mid+1,t,rs(p)));
return ans;
}//Max
void Cover_on_tree(int x,int y,int k)
{
while(top[x]!=top[y])
{
if(deep[top[x]]>deep[top[y]]) swap(x,y);
Cover(rk[top[y]],rk[y],k,1,n,1);
y=fa[top[y]];
}
if(x!=y)
{
if(deep[x]>deep[y]) swap(x,y);
Cover(rk[son[x]],rk[y],k,1,n,1);
}
}
void update_on_tree(int x,int y,int k)
{
while(top[x]!=top[y])
{
if(deep[top[x]]>deep[top[y]]) swap(x,y);
update(rk[top[y]],rk[y],k,1,n,1);
y=fa[top[y]];
}
if(x!=y)
{
if(deep[x]>deep[y]) swap(x,y);
update(rk[son[x]],rk[y],k,1,n,1);
}
}
int query_on_tree(int x,int y)
{
int ans=LLONG_MIN;
while(top[x]!=top[y])
{
if(deep[top[x]]>deep[top[y]]) swap(x,y);
ans=max(ans,query(rk[top[y]],rk[y],1,n,1));
y=fa[top[y]];
}
if(x!=y)
{
if(deep[x]>deep[y]) swap(x,y);
ans=max(ans,query(rk[son[x]],rk[y],1,n,1));
}
return ans;
}
signed main()
{
freopen("P4315_1.in","r",stdin);
freopen("P4315.out","w",stdout);
cin>>n;
for(int i=1;i<n;i++)
{
cin>>u[i]>>v[i]>>w[i];
edge[u[i]].push_back((Edge){v[i],w[i]});
edge[v[i]].push_back((Edge){u[i],w[i]});
}
dfs1(1,1);
dfs2(1,1);
build(1,n,1);
for(int i=1;i<n;i++)
{
if(fa[u[i]]==v[i])
swap(u[i],v[i]);
Cover(rk[v[i]],rk[v[i]],w[i],1,n,1);
}
while(op!="Stop")
{
cin>>op;
if(op=="Change")
{
cin>>l>>k;
Cover(rk[v[l]],rk[v[l]],k,1,n,1);
}
else if(op=="Cover")
{
cin>>l>>r>>k;
Cover_on_tree(l,r,k);
}
else if(op=="Add")
{
cin>>l>>r>>k;
update_on_tree(l,r,k);
}
else if(op=="Max")
{
cin>>l>>r;
cout<<query_on_tree(l,r)<<'\n';
}
}
return 0;
}
下数据点看是 Max 函数错了