2018-team4-modules-LCT

从 Trac 迁移的文章

这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。

原文章内容如下:

{{{
struct Node{
    Node *ch[2],*fa;
    int tag;
}mem[maxn],*null,*it;
inline void init(){
    it = mem;null = it++;
    null->ch[0] = null->ch[1] = null->fa = null;
    null->tag = 0;
}
inline void newNode(){
    Node *p = it++;p->tag = 0;
    p->ch[0] = p->ch[1] = p->fa = null;
}
inline void rotate(Node *p,Node *x){
    int k = x->ch[1] == p;
    Node *y = p->ch[k^1],*z = x->fa;
    if(z->ch[0] == x) z->ch[0] = p;
    if(z->ch[1] == x) z->ch[1] = p;
    if(y != null) y->fa = x;
    p->fa = z;p->ch[k^1] = x;
    x->fa = p;x->ch[k] = y;
}
inline void pushdown(Node *p){
    if(p == null) return;
    if(p->tag){
        if(p->ch[0] != null) p->ch[0]->tag ^= 1;
        if(p->ch[1] != null) p->ch[1]->tag ^= 1;
        swap(p->ch[0],p->ch[1]);p->tag = 0;
    }
}
inline bool isroot(Node *p){
    return (p == null) || (p->fa->ch[0] != p && p->fa->ch[1] != p);
}
inline void Splay(Node *p){
    pushdown(p);
    while(!isroot(p)){
        Node *x = p->fa,*y = x->fa;
        pushdown(y);pushdown(x);pushdown(p);
        if(isroot(x)) rotate(p,x);
        else if((x->ch[0] == p) ^ (y->ch[0] == x)) rotate(p,x),rotate(p,y);
        else rotate(x,y),rotate(p,x);
    }
}
inline Node* Access(Node *x){
    for(Node *y = null;x != null;y = x,x=x->fa)
        Splay(x),x->ch[1] = y;
    return x;
}
inline void makeRoot(Node *x){
    Access(x);Splay(x);x->tag ^= 1;
}
inline Node* findRoot(Node *x){
    Access(x);Splay(x);
    while(x->ch[0] != null) x = x->ch[0];
    Splay(x);return x;
}
inline void link(Node *u,Node *v){
    makeRoot(u);u->fa = v;
}
inline void cut(Node *u,Node *v){
    makeRoot(u);Access(v);Splay(v);
    v->ch[0] = v->ch[0]->fa = null;
}
}}}
struct Node{
    Node *ch[2],*fa;
    int tag;
}mem[maxn],*null,*it;
inline void init(){
    it = mem;null = it++;
    null->ch[0] = null->ch[1] = null->fa = null;
    null->tag = 0;
}
inline void newNode(){
    Node *p = it++;p->tag = 0;
    p->ch[0] = p->ch[1] = p->fa = null;
}
inline void rotate(Node *p,Node *x){
    int k = x->ch[1] == p;
    Node *y = p->ch[k^1],*z = x->fa;
    if(z->ch[0] == x) z->ch[0] = p;
    if(z->ch[1] == x) z->ch[1] = p;
    if(y != null) y->fa = x;
    p->fa = z;p->ch[k^1] = x;
    x->fa = p;x->ch[k] = y;
}
inline void pushdown(Node *p){
    if(p == null) return;
    if(p->tag){
        if(p->ch[0] != null) p->ch[0]->tag ^= 1;
        if(p->ch[1] != null) p->ch[1]->tag ^= 1;
        swap(p->ch[0],p->ch[1]);p->tag = 0;
    }
}
inline bool isroot(Node *p){
    return (p == null) || (p->fa->ch[0] != p && p->fa->ch[1] != p);
}
inline void Splay(Node *p){
    pushdown(p);
    while(!isroot(p)){
        Node *x = p->fa,*y = x->fa;
        pushdown(y);pushdown(x);pushdown(p);
        if(isroot(x)) rotate(p,x);
        else if((x->ch[0] == p) ^ (y->ch[0] == x)) rotate(p,x),rotate(p,y);
        else rotate(x,y),rotate(p,x);
    }
}
inline Node* Access(Node *x){
    for(Node *y = null;x != null;y = x,x=x->fa)
        Splay(x),x->ch[1] = y;
    return x;
}
inline void makeRoot(Node *x){
    Access(x);Splay(x);x->tag ^= 1;
}
inline Node* findRoot(Node *x){
    Access(x);Splay(x);
    while(x->ch[0] != null) x = x->ch[0];
    Splay(x);return x;
}
inline void link(Node *u,Node *v){
    makeRoot(u);u->fa = v;
}
inline void cut(Node *u,Node *v){
    makeRoot(u);Access(v);Splay(v);
    v->ch[0] = v->ch[0]->fa = null;
}