#include <cstdio> #include <algorithm>using namespace std; #define INF 2147483647#define N 20001#define Lson Rt<<1,l,m#define Rson Rt<<1|1,m+1,rint V[n<<1],first[n],next[n<<1],en,bw[n<<1],dw[n <<1];void addedge (int u,int v,int W) {v[++en]=v;bw[en]=w;next[en]=first[u];first[u]=en;} int n,fa[n],top[n],tot,dep[n],siz[n],son[n],num[n],dy[n],m,map[n];void dfs (int U) {siz[u]=1;for (int i=first[U];i;i= Next[i]) if (V[i]!=fa[u]) {dy[(i+1) >>1]=v[i]; Dw[v[i]]=bw[i]; Fa[v[i]]=u; dep[v[i]]=dep[u]+1; DFS (V[i]); Siz[u]+=siz[v[i]]; if (Siz[v[i]]>siz[son[u]]) son[u]=v[i]; }}void df2 (int U) {num[u]=++tot; Map[tot]=u;if (Son[u]) {top[son[u]]=top[u]; DF2 (Son[u]); }for (int i=first[u];i;i=next[i]) if (V[i]!=fa[u]&&v[i]!=son[u]) {top[v[i]]=v[i]; DF2 (V[i]); }}int sumv[n<<2],maxv[n<<2],minv[n<<2];bool rev[n<<2];void work (int rt) {Rev[rt]^=1;sumv[rt ]*= ( -1); swap (Maxv[rt],minv[rt]); maxv[rt]*= ( -1); minv[rt]*= (-1);} void PUshdown (int rt) {if (Rev[rt]) {work (rt<<1); Work (rt<<1|1); rev[rt]=0; }}void pushup (int rt) {Sumv[rt]=sumv[rt<<1]+sumv[rt<<1|1];maxv[rt]=max (maxv[rt<<1],maxv[rt< <1|1]); Minv[rt]=min (minv[rt<<1],minv[rt<<1|1]);} void Buildtree (int rt,int l,int R) {if (l==r) {sumv[rt]=minv[rt]=maxv[rt]=dw[map[l]]; Return }int m= (l+r>>1); Buildtree (Lson); Buildtree (Rson);p ushup (RT);} void update (int p,int v,int rt,int l,int R) {if (l==r) {sumv[rt]=minv[rt]=maxv[rt]=v; Return }pushdown (RT), int m= (l+r>>1), if (p<=m) update (P,v,lson), Else Update (P,v,rson);P ushup (RT);} void reverse (int ql,int qr,int rt,int l,int R) {if (QL<=L&&R<=QR) {work (RT); Return }int m= (l+r>>1);p Ushdown (RT), if (ql<=m) reverse (Ql,qr,lson), if (M<QR) reverse (Ql,qr,rson);p ushup (RT);} void Reverse (int u,int V) {while (Top[u]!=top[v]) {if (Dep[top[u]]<dep[top[v]) swap (U,V); Reverse (num[top[u]],num[u],1,1,n); U=fa[top[u]]; }if (u!=v) {if (DEP[U]>DEP[V]) swap (U,V); reverse (num[u]+1,num[v],1,1,n); }}int qsum (int ql,int qr,int rt,int l,int R) {if (QL<=L&&R<=QR) return sumv[rt];int m= (l+r>>1), res=0; Pushdown (RT), if (ql<=m) res+=qsum (Ql,qr,lson), if (M<QR) res+=qsum (Ql,qr,rson); return res;} int qsum (int u,int V) {int res=0;while (Top[u]!=top[v]) {if (Dep[top[u]]<dep[top[v]]) swap (U,V); Res+=qsum (Num[top[u]],num[u],1,1,n); U=fa[top[u]]; }if (u!=v) {if (Dep[u]>dep[v]) swap (U,V); Res+=qsum (num[u]+1,num[v],1,1,n); }return Res;} int Qmax (int ql,int qr,int rt,int l,int R) {if (QL<=L&&R<=QR) return maxv[rt];int m= (l+r>>1), Res=-INF ;P Ushdown (RT), if (ql<=m) Res=max (Res,qmax (Ql,qr,lson)), if (M<QR) Res=max (Res,qmax (Ql,qr,rson)), return res;} int Qmax (int u,int V) {int res=-inf;while (Top[u]!=top[v]) {if (Dep[top[u]]<dep[top[v]]) swap (U,V); Res=max (Res,qmax (num[top[u]],num[u],1,1,n)); U=fa[top[u]]; }if (u!=v) {if (Dep[u]>dep[v]) swap (U,V); Res=max (Res,qmax (NUM[U]+1,NUM[V), 1,1,n)); }return Res;} int qmin (int ql,int qr,int rt,int l,int R) {if (QL<=L&&R<=QR) return minv[rt];int m= (l+r>>1), Res=INF; Pushdown (RT), if (ql<=m) res=min (Res,qmin (Ql,qr,lson)), if (M<QR) res=min (Res,qmin (Ql,qr,rson)); return res;} int qmin (int u,int V) {int res=inf;while (Top[u]!=top[v]) {if (Dep[top[u]]<dep[top[v]]) swap (U,V); Res=min (Res,qmin (num[top[u]],num[u],1,1,n)); U=fa[top[u]]; }if (u!=v) {if (Dep[u]>dep[v]) swap (U,V); Res=min (Res,qmin (num[u]+1,num[v],1,1,n)); }return Res;} int main () {char op[4];int x,y,z;scanf ("%d", &n), for (int i=1;i<n;++i) {scanf ("%d%d%d", &x,&y,&z); Addedge (X+1,Y+1,Z); Addedge (Y+1,X+1,Z); }top[1]=1;dfs (1);d F2 (1), Buildtree (1,1,n), scanf ("%d", &m), for (; m;--m) {scanf ("%s%d%d", op,&x,&y); if (op[0]== ' C ') update (NUM[DY[X]],Y,1,1,N); else if (op[0]== ' N ') Reverse (x+1,y+1); else if (op[0]== ' S ') printf ("%d\n", Qsum (x+1,y+1)); else if (op[1]== ' A ') printf ("%d\n", Qmax (x+1,y+1)); else printf ("%d\n", QMIN (x+1,y+1)); }return 0;}
Tree chain split segment tree bzoj2157 tour