省选模版复习——LCT

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;
}


你可能感兴趣的:(tree,link,cut)