RT,代码如下
#include<bits/stdc++.h>
#define MAXN 200002
#define ls(x) x<<1
#define rs(x) x<<1|1
using namespace std;
int n,m;
int head[MAXN],fr[MAXN],to[MAXN],nxt[MAXN],w[MAXN],cnt;
int siz[MAXN],son[MAXN],top[MAXN],val[MAXN],fa[MAXN],dfn[MAXN],dep[MAXN],num;
int a[MAXN<<2],sum[MAXN<<2],maxx[MAXN<<2],minn[MAXN<<2];
bool tag[MAXN<<2];
void add_edge(int x,int y,int val)
{
to[++cnt]=y;
fr[cnt]=x;
w[cnt]=val;
nxt[cnt]=head[x];
head[x]=cnt;
}
void dfs1(int u)
{
siz[u]=1;
son[u]=-1;
for(int i=head[u];i;i=nxt[i])
{
int v=to[i];
if(v==fa[u])continue;
fa[v]=u;
dep[v]=dep[u]+1;
dfs1(v);
siz[u]+=siz[v];
val[v]=w[i];
if(son[u]==-1||siz[v]>siz[son[u]])son[u]=v;
}
return;
}
void dfs2(int u,int topn)
{
top[u]=topn;
dfn[u]=++num;
a[num]=val[u];
if(son[u]==-1)return;
dfs2(son[u],topn);
for(int i=head[u];i;i=nxt[i])
{
int v=to[i];
if(v==fa[u]||v==son[u])continue;
dfs2(v,v);
}
return;
}
void push_up(int p)
{
sum[p]=sum[ls(p)]+sum[rs(p)];
maxx[p]=max(maxx[ls(p)],maxx[rs(p)]);
minn[p]=min(minn[ls(p)],minn[rs(p)]);
return;
}
void push_down(int p)
{
if(tag[p])
{
sum[ls(p)]=-sum[ls(p)];
swap(minn[ls(p)],maxx[ls(p)]);
minn[ls(p)]=-minn[ls(p)];
maxx[ls(p)]=-maxx[ls(p)];
tag[ls(p)]=tag[p];
sum[rs(p)]=-sum[rs(p)];
swap(minn[rs(p)],maxx[rs(p)]);
minn[rs(p)]=-minn[rs(p)];
maxx[rs(p)]=-maxx[rs(p)];
tag[rs(p)]=tag[p];
tag[p]=false;
}
return;
}
void build(int l,int r,int p)
{
if(l==r)
{
sum[p]=maxx[p]=minn[p]=a[l];
return;
}
int mid=(l+r)>>1;
build(l,mid,ls(p));build(mid+1,r,rs(p));
push_up(p);
return;
}
void update(int l,int r,int s,int t,int p)
{
if(s>=l&&t<=r)
{
sum[p]=-sum[p];
swap(minn[p],maxx[p]);
minn[p]=-minn[p];
maxx[p]=-maxx[p];
tag[p]=!tag[p];
return;
}
push_down(p);
int mid=(s+t)>>1;
if(mid>=l)update(l,r,s,mid,ls(p));
if(mid<r)update(l,r,mid+1,t,rs(p));
push_up(p);
return;
}
void change(int goal,int s,int t,int p,int k)
{
if(s==t&&s==goal)
{
sum[p]=maxx[p]=minn[p]=k;
return;
}
int mid=(s+t)>>1;
if(mid>=goal)change(goal,s,mid,ls(p),k);
if(mid<goal)change(goal,mid+1,t,rs(p),k);
push_up(p);
return;
}
int query_sum(int l,int r,int s,int t,int p)
{
if(s>=l&&t<=r)
return sum[p];
push_down(p);
int mid=(s+t)>>1,res=0;
if(mid>=l)res+=query_sum(l,r,s,mid,ls(p));
if(mid<r)res+=query_sum(l,r,mid+1,t,rs(p));
return res;
}
int query_max(int l,int r,int s,int t,int p)
{
if(s>=l&&t<=r)
return maxx[p];
push_down(p);
int mid=(s+t)>>1,res=-114514;
if(mid>=l)res=max(res,query_max(l,r,s,mid,ls(p)));
if(mid<r)res=max(res,query_max(l,r,mid+1,t,rs(p)));
return res;
}
int query_min(int l,int r,int s,int t,int p)
{
if(s>=l&&t<=r)
return minn[p];
push_down(p);
int mid=(s+t)>>1,res=114514;
if(mid>=l)res=min(res,query_min(l,r,s,mid,ls(p)));
if(mid<r)res=min(res,query_min(l,r,mid+1,t,rs(p)));
return res;
}
void upd_range(int u,int v)
{
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]])swap(u,v);
update(dfn[top[u]],dfn[u],1,n,1);
u=fa[top[u]];
}
if(dep[u]>dep[v])swap(u,v);
update(dfn[u]+1,dfn[v],1,n,1);
return;
}
void change_point(int u,int w)
{
change(dfn[u],1,n,1,w);
return;
}
int query_sum_range(int u,int v)
{
int sum=0;
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]])swap(u,v);
sum+=query_sum(dfn[top[u]],dfn[u],1,n,1);
u=fa[top[u]];
}
if(dep[u]>dep[v])swap(u,v);
sum+=query_sum(dfn[u]+1,dfn[v],1,n,1);
return sum;
}
int query_max_range(int u,int v)
{
int res=-114514;
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]])swap(u,v);
res=max(res,query_max(dfn[top[u]],dfn[u],1,n,1));
u=fa[top[u]];
}
if(dep[u]>dep[v])swap(u,v);
res=max(res,query_max(dfn[u]+1,dfn[v],1,n,1));
return res;
}
int query_min_range(int u,int v)
{
int res=114514;
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]])swap(u,v);
res=min(res,query_min(dfn[top[u]],dfn[u],1,n,1));
u=fa[top[u]];
}
if(dep[u]>dep[v])swap(u,v);
res=min(res,query_min(dfn[u]+1,dfn[v],1,n,1));
return res;
}
int main()
{
freopen("P1505.in","r",stdin);
freopen("P1505.out","w",stdout);
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<n;i++)
{
int u,v,w;
cin>>u>>v>>w;
add_edge(u+1,v+1,w);add_edge(v+1,u+1,w);
}
dfs1(1);
dfs2(1,1);
build(1,n,1);
cin>>m;
for(int i=1;i<=m;i++)
{
string str;
cin>>str;
int u,v;
cin>>u>>v;
if(str=="C")
{
u<<=1;
int x=fr[u],y=to[u];
if(dep[x]>dep[y])swap(x,y);
change_point(y,v);
}
if(str=="N")
upd_range(u+1,v+1);
if(str=="SUM")
cout<<query_sum_range(u+1,v+1)<<endl;
if(str=="MAX")
cout<<query_max_range(u+1,v+1)<<endl;
if(str=="MIN")
cout<<query_min_range(u+1,v+1)<<endl;
}
return 0;
}