rt,代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N=4e5+10,inf=0x3f3f3f3f;
int n,m;
int h[2*N],e[2*N],ne[2*N],w[2*N],idx=1;
int size[N],root=1,zs=N,id[N],top[N],cnt,cnt2,cnt3;
int f[N],deep[N],egd[N],maxson[N];
int a[N],regd[N],id2[N],mark[4*N],id1[N];
struct node
{
int l,r,maxv,minv,sum;
}t[4*N];
void add(int a,int b,int c)
{
e[idx]=b;
w[idx]=c;
ne[idx]=h[a];
h[a]=idx++;
}
void pushup2(node &a,node b,node c)
{
a.minv=min(b.minv,c.minv);
a.maxv=max(b.maxv,c.maxv);
a.sum=b.sum+c.sum;
}
void pushup(int u)
{
pushup2(t[u],t[2*u],t[2*u+1]);
}
void dfs1(int u,int fa)
{
int zd=0;
size[u]=1;
for(int i=h[u];i!=-1;i=ne[i])
{
int v=e[i];
if(v==fa)continue;
dfs1(v,u);
if(size[v]>zd)zd=size[v];
}
zd=max(zd,n-size[u]);
if(zd<zs)zs=zd,root=u;
}
void dfs2(int u,int fa)
{
int sum=0;
size[u]=1;
deep[u]=deep[fa]+1,f[u]=fa;
for(int i=h[u];i!=-1;i=ne[i])
{
int v=e[i];
if(v==fa)continue;
dfs2(v,u);
a[v]=w[i];
id2[id1[i]]=v;
size[u]+=size[v];
if(size[v]>sum)sum=size[v],maxson[u]=v;
}
}
void dfs3(int u)
{
id[u]=cnt2,egd[u]=++cnt,regd[cnt]=u;
if(maxson[u])dfs3(maxson[u]);
for(int i=h[u];i!=-1;i=ne[i])
{
int v=e[i];
if(id[v])continue;
top[++cnt2]=v;
dfs3(v);
}
}
void build(int u,int l,int r)
{
if(l==r)
{
t[u]={l,l,a[regd[l]],a[regd[l]],a[regd[l]]};
return;
}
t[u]={l,r};
int mid=(l+r)/2;
build(2*u,l,mid);
build(2*u+1,mid+1,r);
pushup(u);
}
void pushdown(int u)
{
int a=t[2*u].minv;
t[2*u].minv=-t[2*u].maxv;
t[2*u].maxv=-a;
t[2*u].sum*=-1;
mark[2*u]^=1;
a=t[2*u+1].minv;
t[2*u+1].minv=-t[2*u+1].maxv;
t[2*u+1].maxv=-a;
t[2*u+1].sum*=-1;
mark[2*u+1]^=1;
mark[u]=0;
}
void change(int u,int l,int r,int k)
{
if(l<=t[u].l&&t[u].r<=r)
{
if(k!=inf)t[u].minv=t[u].maxv=t[u].sum=k;
else
{
swap(t[u].maxv,t[u].minv);
t[u].minv*=-1;
t[u].maxv*=-1;
t[u].sum*=-1;
mark[u]^=1;
}
return;
}
if(mark[u])pushdown(u);
int mid=(t[u].l+t[u].r)/2;
if(l<=mid)change(2*u,l,r,k);
if(r>mid)change(2*u+1,l,r,k);
pushup(u);
}
int lca(int a,int b)
{
while(id[a]!=id[b])
{
if(deep[top[id[a]]]<deep[top[id[b]]])swap(a,b);
a=f[top[id[a]]];
}
return deep[a]<deep[b]?a:b;
}
void sumchange(int a,int b)
{
while(id[a]!=id[b])
{
if(deep[top[id[a]]]<deep[top[id[b]]])swap(a,b);
change(1,egd[top[id[a]]],egd[a],inf);
a=f[top[id[a]]];
}
if(deep[a]<deep[b])swap(a,b);
change(1,egd[b],egd[a],inf);
}
node ask(int u,int l,int r)
{
if(l<=t[u].l&&t[u].r<=r)
return t[u];
if(mark[u])pushdown(u);
int mid=(t[u].l+t[u].r)/2;
node x;
if(l<=mid&&mid<r)
{
node y=ask(2*u,l,r),z=ask(2*u+1,l,r);
pushup2(x,y,z);
}
else if(l<=mid)x=ask(2*u,l,r);
else x=ask(2*u+1,l,r);
return x;
}
int sumask1(int a,int b)
{
int sum=0;
while(id[a]!=id[b])
{
if(deep[top[id[a]]]<deep[top[id[b]]])swap(a,b);
sum+=ask(1,egd[top[id[a]]],egd[a]).sum;
a=f[top[id[a]]];
}
if(deep[a]<deep[b])swap(a,b);
sum+=ask(1,egd[b],egd[a]).sum;
return sum;
}
int sumask2(int a,int b)
{
int sum=-inf;
while(id[a]!=id[b])
{
if(deep[top[id[a]]]<deep[top[id[b]]])swap(a,b);
sum=max(sum,ask(1,egd[top[id[a]]],egd[a]).maxv);
a=f[top[id[a]]];
}
if(deep[a]<deep[b])swap(a,b);
sum=max(sum,ask(1,egd[b],egd[a]).maxv);
return sum;
}
int sumask3(int a,int b)
{
int sum=inf;
while(id[a]!=id[b])
{
if(deep[top[id[a]]]<deep[top[id[b]]])swap(a,b);
sum=min(sum,ask(1,egd[top[id[a]]],egd[a]).minv);
a=f[top[id[a]]];
}
if(deep[a]<deep[b])swap(a,b);
sum=min(sum,ask(1,egd[b],egd[a]).minv);
return sum;
}
int find(int a,int b)
{
while(id[a]!=id[b])
{
if(deep[top[id[a]]]<deep[top[id[b]]])swap(a,b);
if(deep[top[id[a]]]==deep[b]+1)break;
a=f[top[id[a]]];
}
if(deep[a]<deep[b])swap(a,b);
while(f[a]!=b)a=f[a];
return a;
}
int main()
{
memset(h,-1,sizeof h);
scanf("%d",&n);
for(int i=1;i<n;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
id1[idx]=id1[idx+1]=++cnt3;
add(a,b,c),add(b,a,c);
}
dfs1(1,1);
dfs2(root,root);
top[++cnt2]=root;
dfs3(root);
build(1,1,n);
scanf("%d",&m);
char op[10];
int a,b;
for(int i=1;i<=m;i++)
{
scanf("%s%d%d",&op,&a,&b);
if(op[0]=='C')
change(1,egd[id2[a]],egd[id2[a]],b);
else if(op[0]=='N')
{
int l=lca(a,b);
change(1,egd[l],egd[l],inf);
sumchange(a,b);
}
else
{
int l=lca(a,b);
if(l!=a&&l!=b)
{
int a2=a,b2=b;
a2=find(a,l);
b2=find(b,l);
if(op[0]=='S')
cout<<sumask1(a,a2)+sumask1(b,b2)<<endl;
else if(op[1]=='A')
cout<<max(sumask2(a,a2),sumask2(b,b2))<<endl;
else if(op[1]=='I')
cout<<min(sumask3(a,a2),sumask3(b,b2))<<endl;
}
else
{
if(deep[a]<deep[b])swap(a,b);
int c;
c=find(a,l);
if(op[0]=='S')
cout<<sumask1(a,c)<<endl;
else if(op[1]=='A')
cout<<sumask2(a,c)<<endl;
else if(op[1]=='I')
cout<<sumask3(a,c)<<endl;
}
}
}
return 0;
}