bzoj2157 LCT裸题
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int INF=1e9; const int Maxn=40005; int son[Maxn][2],sum[Maxn],minx[Maxn],maxx[Maxn]; int inv[Maxn],rev[Maxn],w[Maxn],fa[Maxn]; int n,m,x,y,i,a,u,v; #define isroot(x) ( !((son[fa[x]][0]==x)||(son[fa[x]][1]==x)) ) void push1(int x){ swap(son[x][0],son[x][1]); if (son[x][0]) rev[son[x][0]] ^= 1; if (son[x][1]) rev[son[x][1]] ^= 1; rev[x] = 0; } void push2(int x){ int L = son[x][0], R = son[x][1]; if (L){ sum[L] = -sum[L]; swap(minx[L],maxx[L]); minx[L] = -minx[L]; maxx[L] = -maxx[L]; inv[L] ^= 1; if (L>n) w[L]=-w[L]; } if (R){ sum[R] = -sum[R]; swap(minx[R],maxx[R]); minx[R] = -minx[R]; maxx[R] = -maxx[R]; inv[R] ^= 1; if (R>n) w[R]=-w[R]; } inv[x] = 0; } void update(int x){ sum[x] = sum[son[x][0]]+sum[son[x][1]]+w[x]; minx[x] = min(minx[son[x][0]], minx[son[x][1]]); maxx[x] = max(maxx[son[x][0]], maxx[son[x][1]]); if (x>n){ minx[x] = min(w[x], minx[x]); maxx[x] = max(w[x], maxx[x]); } } void rotate(int x,int ft,int K){ if (!isroot(ft)){ if (son[fa[ft]][0]==ft) son[fa[ft]][0] = x; else son[fa[ft]][1] = x; } fa[x] = fa[ft]; if (son[x][K^1]) fa[son[x][K^1]]=ft; son[ft][K] = son[x][K^1]; son[x][K^1] = ft; fa[ft] = x; update(ft); } void Splay(int x){ int ft, gf; while (!isroot(x)){ ft = fa[x]; gf = fa[ft]; if (rev[gf]) push1(gf); if (inv[gf]) push2(gf); if (rev[ft]) push1(ft); if (inv[ft]) push2(ft); if (rev[x]) push1(x); if (inv[x]) push2(x); if (isroot(ft)){ if (son[ft][0]==x) rotate(x,ft,0); if (son[ft][1]==x) rotate(x,ft,1); } else { if (son[ft][0]==x && son[gf][0]==ft) rotate(ft,gf,0), rotate(x,ft,0); if (son[ft][1]==x && son[gf][1]==ft) rotate(ft,gf,1), rotate(x,ft,1); if (son[ft][0]==x && son[gf][1]==ft) rotate(x,ft,0), rotate(x,gf,1); if (son[ft][1]==x && son[gf][0]==ft) rotate(x,ft,1), rotate(x,gf,0); } } if (rev[x]) push1(x); if (inv[x]) push2(x); update(x); } void access(int x){ int t = 0; while (x){ Splay(x); son[x][1] = t; update(x); t = x; x = fa[x]; } } void makeroot(int x) { access(x); Splay(x); rev[x]^=1; } void Link(int x,int y) { makeroot(x); fa[x]=y; access(x); } void cut(int x,int y){ makeroot(x); access(y); Splay(y); son[y][0] = 0; fa[x] = 0; Splay(x); Splay(y); } int main(){ //freopen("2157.in","r",stdin); //freopen("2157.out","w",stdout); scanf("%d",&n); minx[0] = INF; maxx[0] = -INF; for (i=1;i<n;i++){ scanf("%d%d%d",&x,&y,&w[n+i]); x++; y++; Link(x,n+i); Link(y,n+i); } scanf("%d\n",&m); char S[5]; while (m--){ scanf("%s",S); if (S[0]=='C'){ scanf("%d%d\n",&i,&a); makeroot(i+n); w[i+n] = a; update(i+n); } else if (S[0]=='N'){ scanf("%d%d\n",&u,&v); u++; v++; makeroot(u); access(v); Splay(v); sum[v] = -sum[v]; swap(minx[v],maxx[v]); minx[v] = -minx[v]; maxx[v] = -maxx[v]; inv[v] ^= 1; } else if (S[0]=='S'){ scanf("%d%d\n",&u,&v); u++; v++; makeroot(u); access(v); Splay(v); printf("%d\n",sum[v]); } else if (S[1]=='A'){ scanf("%d%d\n",&u,&v); u++; v++; makeroot(u); access(v); Splay(v); printf("%d\n",maxx[v]); } else { scanf("%d%d\n",&u,&v); u++; v++; makeroot(u); access(v); Splay(v); printf("%d\n",minx[v]); } } return 0; }