树剖第一遍dfs结点sz初值写错了设的0,但是判了重儿子编号为0就换一个重儿子,相当于是随便选了一个子结点当重儿子,但是过了(
#include<bits/stdc++.h>
#define ll long long
#define inf 1000000000
#define otto auto
#define N 200010
using namespace std;
struct E
{
int to,w,ne,nb;
}e[N<<1];
struct R
{
int ls,rs;
int lz,zs,fs,ma,mi;
}t[N<<2];
int n,ct,tt;
int fa[N],nt[N],bl[N],et[N],tp[N],sz[N],hs[N];
int d[N],h[N],a[N];
void ade(int x,int y,int w,int i)
{
e[++ct].to=y;
e[ct].w=w;
e[ct].nb=i;
e[ct].ne=h[x];
h[x]=ct;
}
void pu(int x)
{
int ls=t[x].ls,rs=t[x].rs;
t[x].ma=max(t[ls].ma,t[rs].ma);
t[x].mi=min(t[ls].mi,t[rs].mi);
t[x].zs=t[ls].zs+t[rs].zs;
t[x].fs=t[ls].fs+t[rs].fs;
}
void chg(int x)
{
swap(t[x].ma,t[x].mi);
swap(t[x].fs,t[x].zs);
t[x].zs=-t[x].zs;
t[x].fs=-t[x].fs;
t[x].ma=-t[x].ma;
t[x].mi=-t[x].mi;
t[x].lz^=1;
}
void pd(int x)
{
if(!t[x].lz)return;
chg(t[x].ls);
chg(t[x].rs);
t[x].lz=0;
}
void dfs(int x)
{
sz[x]=0;
int i,y;
for(i=h[x];i;i=e[i].ne)
{
y=e[i].to;
if(y==fa[x])continue;
fa[y]=x;
d[y]=d[x]+1;
a[y]=e[i].w;
et[e[i].nb]=y;
dfs(y);
sz[x]+=sz[y];
if(sz[y]>sz[hs[x]]||!hs[x])hs[x]=y;
}
}
void dfss(int x,int t)
{
tp[x]=t;
if(x)
{
bl[x]=++ct;
nt[ct]=x;
}
if(hs[x])dfss(hs[x],t);
int y,i;
for(i=h[x];i;i=e[i].ne)
{
y=e[i].to;
if(y==fa[x]||y==hs[x])continue;
dfss(y,y);
}
}
int bu(int l,int r)
{
int x=++tt;
if(l==r)
{
if(a[nt[l]]>=0)
t[x].zs=a[nt[l]];
else
t[x].fs=a[nt[l]];
t[x].ma=t[x].mi=a[nt[l]];
return x;
}
int mid=(l+r)>>1;
t[x].ls=bu(l,mid);
t[x].rs=bu(mid+1,r);
pu(x);
return x;
}
void upd(int x,int l,int r,int k,int w)
{
if(l==r)
{
t[x].ma=t[x].mi=w;
t[x].zs=t[x].fs=0;
if(w>=0)t[x].zs=w;
else t[x].fs=w;
return;
}
pd(x);
int mid=(l+r)>>1;
if(k<=mid)upd(t[x].ls,l,mid,k,w);
else upd(t[x].rs,mid+1,r,k,w);
pu(x);
}
int qry(int x,int l,int r,int le,int ri)
{
if(l>=le&&r<=ri)return t[x].zs+t[x].fs;
// printf("%d l:%d r:%d le:%d ri:%d\n",x,l,r,le,ri);
pd(x);
int mid=(l+r)>>1,ans=0;
if(le<=mid)ans+=qry(t[x].ls,l,mid,le,ri);
if(ri>mid)ans+=qry(t[x].rs,mid+1,r,le,ri);
pu(x);
return ans;
}
int qma(int x,int l,int r,int le,int ri)
{
if(l>=le&&r<=ri)return t[x].ma;
pd(x);
int mid=(l+r)>>1,ans=-inf;
if(le<=mid)ans=max(ans,qma(t[x].ls,l,mid,le,ri));
if(ri>mid)ans=max(ans,qma(t[x].rs,mid+1,r,le,ri));
pu(x);
return ans;
}
int qmi(int x,int l,int r,int le,int ri)
{
if(l>=le&&r<=ri)return t[x].mi;
pd(x);
int mid=(l+r)>>1,ans=inf;
if(le<=mid)ans=min(ans,qmi(t[x].ls,l,mid,le,ri));
if(ri>mid)ans=min(ans,qmi(t[x].rs,mid+1,r,le,ri));
pu(x);
return ans;
}
void urt(int x,int l,int r,int le,int ri)
{
if(l>=le&&r<=ri)
{
chg(x);
return;
}
pd(x);
int mid=(l+r)>>1;
if(le<=mid)urt(t[x].ls,l,mid,le,ri);
if(ri>mid)urt(t[x].rs,mid+1,r,le,ri);
pu(x);
return;
}
void rtl(int x,int y)
{
while(tp[x]!=tp[y])
{
if(d[tp[x]]<d[tp[y]])swap(x,y);
urt(1,1,n,bl[tp[x]],bl[x]);
x=fa[tp[x]];
}
if(x==y)return;
if(d[x]>d[y])swap(x,y);
urt(1,1,n,bl[hs[x]],bl[y]);
}
int qrl(int x,int y)
{
int ans=0;
while(tp[x]!=tp[y])
{
if(d[tp[x]]<d[tp[y]])swap(x,y);
ans+=qry(1,1,n,bl[tp[x]],bl[x]);
x=fa[tp[x]];
}
if(x==y)return ans;
if(d[x]>d[y])swap(x,y);
ans+=qry(1,1,n,bl[hs[x]],bl[y]);
return ans;
}
int qal(int x,int y)
{
int ans=-inf;
while(tp[x]!=tp[y])
{
if(d[tp[x]]<d[tp[y]])swap(x,y);
ans=max(ans,qma(1,1,n,bl[tp[x]],bl[x]));
x=fa[tp[x]];
}
if(x==y)return ans;
if(d[x]>d[y])swap(x,y);
ans=max(ans,qma(1,1,n,bl[hs[x]],bl[y]));
return ans;
}
int qil(int x,int y)
{
int ans=inf;
while(tp[x]!=tp[y])
{
if(d[tp[x]]<d[tp[y]])swap(x,y);
ans=min(ans,qmi(1,1,n,bl[tp[x]],bl[x]));
x=fa[tp[x]];
}
if(x==y)return ans;
if(d[x]>d[y])swap(x,y);
ans=min(ans,qmi(1,1,n,bl[hs[x]],bl[y]));
return ans;
}
signed main()
{
int i,q,x,y,w;
string s;
scanf("%d",&n);
for(i=1;i<n;i++)
{
scanf("%d%d%d",&x,&y,&w);
ade(x,y,w,i);
ade(y,x,w,i);
}
dfs(0);
ct=0;
dfss(0,0);
n--;
bu(1,n);
scanf("%d",&q);
while(q--)
{
cin>>s;
scanf("%d%d",&x,&y);
if(s=="C")
upd(1,1,n,bl[et[x]],y);
if(s=="N")
rtl(x,y);
if(s=="SUM")
printf("%d\n",qrl(x,y));
if(s=="MAX")
printf("%d\n",qal(x,y));
if(s=="MIN")
printf("%d\n",qil(x,y));
}
return 0;
}