不知道为什么有些查询出的值会大一点
#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
const int N=101100;
inline int read()
{
int f=1,x=0; char ch=getchar();
while(!isdigit(ch)) { if(ch=='-') f=-1; ch=getchar(); }
while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar(); }
return f*x;
}
struct node
{
int fa,son;
int dfn,top;
int siz,dep;
int val;
};
struct edge
{ int pos,next,to,dis;};
struct tree
{ int l,r,val,tagR,tagA; };
int head[N],tot;
int w[N],h[N],tim;
int n,g[N<<1];
tree T[N<<2];
edge e[N<<1];
edge E[N];
node p[N];
inline void DoubleEdge(int pos,int u,int v,int w)
{
e[tot]=(edge){ pos,head[u],v,w }; head[u]=tot++;
e[tot]=(edge){ pos,head[v],u,w }; head[v]=tot++;
E[pos]=(edge){ pos,u,v,w };
}
void HeavySon_dfs(int u,int fa)
{
p[u].dep=p[fa].dep+1; p[u].fa=fa; p[u].siz=1;
int mx=-INF;
for(int i=head[u];~i;i=e[i].next)
{
int v=e[i].to;
if(v==fa) continue;
HeavySon_dfs(v,u);
p[u].siz+=p[v].siz;
if(p[v].siz>mx)
{
p[u].son=v;
mx=p[v].siz;
}
}
}
void Time_dfs(int u,int top)
{
p[u].top=top; p[u].dfn=++tim; w[tim]=u;
if(!p[u].son) return ;
Time_dfs(p[u].son,top);
for(int i=head[u];~i;i=e[i].next)
{
int v=e[i].to;
if(v==p[u].fa ) continue;
if(v==p[u].son) continue;
Time_dfs(v,v);
}
}
#define iL i<<1
#define iR i<<1|1
void pushup(int i)
{ T[i].val=max(T[iL].val,T[iR].val); }
void pushadd(int i)
{
if(!T[i].tagA) return ;
T[iL].val +=T[i].tagA*(T[iL].r-T[iL].l+1);
T[iR].val +=T[i].tagA*(T[iR].r-T[iR].l+1);
T[iL].tagA+=T[i].tagA;
T[iR].tagA+=T[i].tagA;
T[i].tagA=0;
}
void pushrep(int i)
{
if(!T[i].tagR) return ;
T[iL].val =T[i].tagR;
T[iL].tagR=T[i].tagR;
T[iR].val =T[i].tagR;
T[iR].tagR=T[i].tagR;
T[i].tagR=0;
}
void pushdown(int i)
{
pushadd(i);
pushrep(i);
}
void build(int i,int l,int r)
{
T[i].l=l,T[i].r=r,T[i].val=0;
if(l==r) return ;
int mid=l+r>>1;
build(iL,l,mid);
build(iR,mid+1,r);
pushup(i);
}
void updata_add(int i,int L,int R,int num)
{
if(L<=T[i].l&&T[i].r<=R)
{
T[i].tagA+=num;
T[i].val +=num*(T[i].r-T[i].l+1);
return ;
}
pushdown(i);
int mid=T[i].l+T[i].r>>1;
if(L<=mid) updata_add(iL,L,R,num);
if(R>mid) updata_add(iR,L,R,num);
pushup(i);
}
void updata_rep(int i,int L,int R,int num)
{
if(L<=T[i].l&&T[i].r<=R)
{
pushadd(i);
T[i].tagR=num;
T[i].val =num;
return ;
}
pushdown(i);
int mid=T[i].l+T[i].r>>1;
if(L<=mid) updata_rep(iL,L,R,num);
if(R>mid) updata_rep(iR,L,R,num);
pushup(i);
}
int query(int i,int L,int R)
{
if(L<=T[i].l&&T[i].r<=R)
return T[i].val;
pushdown(i);
int mid=T[i].l+T[i].r>>1,sum=-INF;
if(L<=mid) sum=max(sum,query(iL,L,R));
if(R>mid) sum=max(sum,query(iR,L,R));
return sum;
}
void Updata_Add(int u,int v,int num)
{
while(p[u].top!=p[v].top)
{
if(p[p[u].top].dep<p[p[v].top].dep) swap(u,v);
updata_add(1,p[p[u].top].dfn,p[u].dfn,num);
u=p[p[u].top].fa;
}
if(p[u].dep>p[v].dep) swap(u,v);
updata_add(1,p[u].dfn,p[v].dfn,num);
}
void Updata_Rep(int u,int v,int num)
{
while(p[u].top!=p[v].top)
{
if(p[p[u].top].dep<p[p[v].top].dep) swap(u,v);
updata_rep(1,p[p[u].top].dfn,p[u].dfn,num);
u=p[p[u].top].fa;
}
if(p[u].dep>p[v].dep) swap(u,v);
updata_rep(1,p[u].dfn,p[v].dfn,num);
}
int Query(int u,int v)
{
int sum=-INF;
while(p[u].top!=p[v].top)
{
if(p[p[u].top].dep<p[p[v].top].dep) swap(u,v);
sum=max(sum,query(1,p[p[u].top].dfn,p[u].dfn));
u=p[p[u].top].fa;
}
if(p[u].dep>p[v].dep) swap(u,v);
sum=max(sum,query(1,p[u].dfn,p[v].dfn));
return sum;
}
signed main()
{
//freopen("P4315.in","r",stdin);
//freopen("P4315.out","w",stdout);
memset(head,-1,sizeof(head));
n=read();
for(int i=1;i<n;i++)
{
int u=read(),v=read(),w=read();
DoubleEdge(i,u,v,w);
}
string s; cin>>s;
HeavySon_dfs(1,0);
Time_dfs(1,1);
build(1,1,n);
for(int i=1;i<n;i++)
{
int u=E[i].next,v=E[i].to;
if(p[u].dep<p[v].dep) swap(u,v);
p[u].val=E[i].dis;
Updata_Rep(u,u,E[i].dis);
}
while(s!="Stop")
{
if(s=="Max")
{
int u=read(),v=read();
printf("%d\n",Query(u,v));
}
if(s=="Change")
{
int k=read(),w=read();
Updata_Rep(g[k],g[k],w);
}
if(s=="Cover")
{
int u=read(),v=read(),w=read();
Updata_Rep(u,v,w);
}
if(s=="Add")
{
int u=read(),v=read(),w=read();
Updata_Add(u,v,w);
}
cin>>s;
}
return 0;
}