模板汇总——LCT

link-cut tree

#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
const int N = 5e5 + 100;
struct Node{
    int rev, rt;
    int son[2], pre;
    int mx, val, id;
    void init(){
        rt = 1; rev = pre = son[0] = son[1] = 0;
        mx = val = id = 0;
    }
}tr[N];
void Push_Rev(int x){
    if(!x) return ;
    swap(lch(x), rch(x));
    tr[x].rev ^= 1;
}
void Push_Up(int x){
    if(!x) return ;
    tr[x].mx = tr[x].val, tr[x].id = x;
    if(tr[x].mx < tr[lch(x)].mx) tr[x].mx = tr[lch(x)].mx, tr[x].id = tr[lch(x)].id;
    if(tr[x].mx < tr[rch(x)].mx) tr[x].mx = tr[rch(x)].mx, tr[x].id = tr[rch(x)].id;
}
void Push_Down(int x){
   if(tr[x].rev){
        tr[x].rev = 0;
        Push_Rev(lch(x));
        Push_Rev(rch(x));
    }
}
void Rev(int x){
    if(!tr[x].rt) Rev(tr[x].pre);
    Push_Down(x);
}
void rotate(int x){
    if(tr[x].rt) return;
    int y = tr[x].pre, z = tr[y].pre;
    int k = (rch(y) == x);
    tr[y].son[k] = tr[x].son[k^1];
    tr[tr[y].son[k]].pre = y;
    tr[x].son[k^1] = y;
    tr[y].pre = x;
    tr[x].pre = z;
    if(tr[y].rt) tr[y].rt = 0, tr[x].rt = 1;
    else tr[z].son[rch(z) == y] = x;
    Push_Up(y);
}
void Splay(int x){
     Rev(x);
     while(!tr[x].rt){
        int y = tr[x].pre, z = tr[y].pre;
        if(!tr[y].rt){
            if(( x == rch(y) ) != (y == rch(z))) rotate(x);
            else rotate(y);
        }
        rotate(x);
    }
    Push_Up(x);
}
void Access(int x){
    int y = 0;
    do{
        Splay(x);
        tr[rch(x)].rt = 1;
        rch(x) = y;
        tr[y].rt = 0;
        Push_Up(x);
        y = x;
        x = tr[x].pre;
    }while(x);
}
void Make_rt(int x){
    Access(x);
    Splay(x);
    Push_Rev(x);
}
bool judge(int u, int v){
    while(tr[u].pre) u = tr[u].pre;
    while(tr[v].pre) v = tr[v].pre;
    return u == v;
}
void link(int u, int v){
    Make_rt(u);
    tr[u].pre = v;
}
void cut(int u, int v){
    Make_rt(u);
    Access(v);
    Splay(v);
    tr[lch(v)].pre = 0;
    tr[lch(v)].rt = 1;
    tr[v].pre = 0;
    lch(v) = 0;
}
View Code

 

 

维护子树。

维护子树就是新开一个状态存一下 所有非偏爱子节点的信息, 然后每次access的时候我们就根据偏爱子节点的变化, 从而更新这个新开的状态。

这个写法 是维护 子树内的亦或和。

代码:

#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
const int N = 5e5 + 100;
struct Node{
    int rev, rt;
    int son[2], pre;
    int sum, vsum, key;
    void init(){
        rt = 1; rev = pre = son[0] = son[1] = 0;
        sum = vsum = key = 0;
    }
}tr[N];
void Push_Rev(int x){
    if(!x) return ;
    swap(lch(x), rch(x));
    tr[x].rev ^= 1;
}
void Push_Up(int x){
    if(!x) return ;
    tr[x].sum = tr[x].key ^ tr[lch(x)].sum ^ tr[rch(x)].sum ^ tr[x].vsum;
}
void Push_Down(int x){
   if(tr[x].rev){
        tr[x].rev = 0;
        Push_Rev(lch(x));
        Push_Rev(rch(x));
    }
}
void Rev(int x){
    if(!tr[x].rt) Rev(tr[x].pre);
    Push_Down(x);
}
void rotate(int x){
    if(tr[x].rt) return;
    int y = tr[x].pre, z = tr[y].pre;
    int k = (rch(y) == x);
    tr[y].son[k] = tr[x].son[k^1];
    tr[tr[y].son[k]].pre = y;
    tr[x].son[k^1] = y;
    tr[y].pre = x;
    tr[x].pre = z;
    if(tr[y].rt) tr[y].rt = 0, tr[x].rt = 1;
    else tr[z].son[rch(z) == y] = x;
    Push_Up(y);
}
void Splay(int x){
     Rev(x);
     while(!tr[x].rt){
        int y = tr[x].pre, z = tr[y].pre;
        if(!tr[y].rt){
            if(( x == rch(y) ) != (y == rch(z))) rotate(x);
            else rotate(y);
        }
        rotate(x);
    }
    Push_Up(x);
}
void Access(int x){
    int y = 0;
    do{
        Splay(x);
        tr[rch(x)].rt = 1;
        tr[x].vsum ^= tr[rch(x)].sum;
        rch(x) = y;
        tr[x].vsum ^= tr[rch(x)].sum;
        tr[y].rt = 0;
        Push_Up(x);
        y = x;
        x = tr[x].pre;
    }while(x);
}
void Make_rt(int x){
    Access(x);
    Splay(x);
    Push_Rev(x);
}
void link(int u, int v){
    Make_rt(u);
    Access(v);
    Splay(v);
    tr[u].pre = v;
    tr[v].
    vsum ^= tr[u].sum;
    Push_Up(v);
}
void cut(int u, int v){
    Make_rt(u);
    Access(v);
    Splay(v);
    tr[lch(v)].pre = 0;
    tr[lch(v)].rt = 1;
    tr[v].pre = 0;
    lch(v) = 0;
    Push_Up(v);
}
View Code

 

posted @ 2018-08-23 16:50  Schenker  阅读(166)  评论(0编辑  收藏  举报