树链剖分,边权存到点上,注意边界处理
#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 100005
using namespace std;
int n,m;
struct edge
{
int to,ne,w;
}b[maxn];
int k=0,head[maxn];
struct tree
{
int l,r,mx,mi,sum;
}t[maxn*4];
struct edge2
{
int s,t,w;
}a[maxn];
int c[maxn];
bool rev[maxn];
int max(int x,int y)
{
return x >y ? x: y;
}
void swap(int &x,int &y)
{
int z=x;x=y;y=z;
}
inline int read()
{
int x=0;char ch=getchar();
while(ch<'0'||ch>'9') ch=getchar();
while(ch>='0'&&ch<='9'){ x=x*10+ch-'0'; ch=getchar(); }
return x;
}
void add(int u,int v,int w)
{
k++;
b[k].to=v;b[k].ne=head[u];b[k].w=w;head[u]=k;
}
int fa[maxn],sz[maxn],son[maxn],d[maxn],top[maxn],id[maxn],pos[maxn];
void dfs1(int x)
{
sz[x]=1;
for(int i=head[x];i!=-1;i=b[i].ne)
if(b[i].to!=fa[x]){
fa[b[i].to]=x; d[b[i].to]=d[x]+1;
c[b[i].to]=b[i].w;
dfs1(b[i].to);
sz[x]+=sz[b[i].to];
if(son[x]==-1) son[x]=b[i].to;
else if(sz[b[i].to]>sz[son[x]]) son[x]=b[i].to;
}
}
int cnt=0;
void dfs2(int x,int tp)
{
id[x]=++cnt; pos[cnt]=x;
top[x]=tp;
if(son[x]!=-1) dfs2(son[x],tp);
for(int i=head[x];i!=-1;i=b[i].ne)
if(b[i].to!=fa[x]&&b[i].to!=son[x]) dfs2(b[i].to,b[i].to);
}
struct Tree
{
void swp(int &x,int &y)
{
int z=x; x=-y; y=-z;
}
void update(int z)
{
t[z].mx=max(t[z<<1].mx,t[z<<1|1].mx);
t[z].mi=min(t[z<<1].mi,t[z<<1|1].mi);
t[z].sum=t[z<<1].sum+t[z<<1|1].sum;
}
void build(int l,int r,int z)
{
t[z].l=l;t[z].r=r;
if(l==r){
t[z].mx=t[z].mi=t[z].sum=c[pos[l]];
return ;
}
int mid=(l+r)>>1;
build(l,mid,z<<1);
build(mid+1,r,z<<1|1);
update(z);
}
void xg(int x,int y,int z)
{
if(t[z].l==t[z].r){
t[z].mx=t[z].mi=t[z].sum=y;
return ;
}
int mid=(t[z].l+t[z].r)>>1;
if(x<=mid) xg(x,y,z<<1);
else xg(x,y,z<<1|1);
update(z);
}
void Rev(int x,int y,int z)
{
if(t[z].l==t[z].r){
t[z].mx*=-1;t[z].mi*=-1;t[z].sum*=-1;
return ;
}
int mid=(t[z].l+t[z].r)>>1;
if(x<=mid) Rev(x,y,z<<1);
if(y>mid) Rev(x,y,z<<1|1);
update(z);
}
int getsum(int x,int y,int z)
{
if(x<=t[z].l&&t[z].r<=y) return t[z].sum;
int ans=0;
int mid=(t[z].l+t[z].r)>>1;
if(x<=mid) ans+=getsum(x,y,z<<1);
if(y>mid) ans+=getsum(x,y,z<<1|1);
return ans;
}
int getmax(int x,int y,int z)
{
if(x<=t[z].l&&t[z].r<=y) return t[z].mx;
int ans=-0x7fffffff;
int mid=(t[z].l+t[z].r)>>1;
if(x<=mid) ans=max(ans,getmax(x,y,z<<1));
if(y>mid) ans=max(ans,getmax(x,y,z<<1|1));
return ans;
}
int getmin(int x,int y,int z)
{
if(x<=t[z].l&&t[z].r<=y) return t[z].mi;
int ans=0x7fffffff;
int mid=(t[z].l+t[z].r)>>1;
if(x<=mid) ans=min(ans,getmin(x,y,z<<1));
if(y>mid) ans=min(ans,getmin(x,y,z<<1|1));
return ans;
}
}tr;
void revc(int x,int y)
{
int fx=top[x],fy=top[y];
while(fx!=fy){
if(d[fx]<d[fy]) { swap(fx,fy); swap(x,y); }
tr.Rev(id[fx],id[x],1);
x=fa[fx]; fx=top[x];
}
if(d[x]>d[y]) swap(x,y);
tr.Rev(id[x]+1,id[y],1);
}
int getsum(int x,int y)
{
int fx=top[x],fy=top[y];
int ans=0;
while(fx!=fy){
if(d[fx]<d[fy]) { swap(fx,fy); swap(x,y); }
ans+=tr.getsum(id[fx],id[x],1);
x=fa[fx]; fx=top[x];
}
if(d[x]>d[y]) swap(x,y);
ans+=tr.getsum(id[x]+1,id[y],1);
return ans;
}
int getmax(int x,int y)
{
int fx=top[x],fy=top[y];
int ans=-0x7fffffff;
while(fx!=fy){
if(d[fx]<d[fy]) { swap(fx,fy); swap(x,y); }
ans=max(ans,tr.getmax(id[fx],id[x],1));
x=fa[fx]; fx=top[x];
}
if(d[x]>d[y]) swap(x,y);
ans=max(ans,tr.getmax(id[x]+1,id[y],1));
return ans;
}
int getmin(int x,int y)
{
int fx=top[x],fy=top[y];
int ans=0x7fffffff;
while(fx!=fy){
if(d[fx]<d[fy]) { swap(fx,fy); swap(x,y); }
ans=min(ans,tr.getmin(id[fx],id[x],1));
x=fa[fx]; fx=top[x];
}
if(d[x]>d[y]) swap(x,y);
ans=min(ans,tr.getmin(id[x]+1,id[y],1));
return ans;
}
int main()
{
//freopen("in.txt","r",stdin);
freopen("nt2011_travel.in","r",stdin);
freopen("nt2011_travel.out","w",stdout);
memset(head,-1,sizeof(head));
memset(son,-1,sizeof(son));
memset(fa,-1,sizeof(fa));
scanf("%d",&n);
int x,y,z;
char type[5];
for(int i=1;i<n;i++){
scanf("%d%d%d",&x,&y,&z);
add(x,y,z); add(y,x,z);
a[i].s=x;a[i].t=y;
}
dfs1(0);
dfs2(0,0);
tr.build(1,n+1,1);
scanf("%d",&m);
while(m--){
scanf("%s",type); scanf("%d%d",&x,&y);
if(type[0]=='C'){
if(fa[a[x].s]==a[x].t) tr.xg(id[a[x].s],y,1);
else tr.xg(id[a[x].t],y,1);
}
if(type[0]=='N') revc(x,y);
if(type[0]=='S') printf("%d\n",getsum(x,y));
if(type[0]=='M'&&type[1]=='A') printf("%d\n",getmax(x,y));
if(type[0]=='M'&&type[1]=='I') printf("%d\n",getmin(x,y));
}
return 0;
}