LCT模板坑点总结

Posted gkeng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LCT模板坑点总结相关的知识,希望对你有一定的参考价值。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN=100005;
int n,m;
struct LCT {
    int fa[MAXN],val[MAXN],rev[MAXN],ch[MAXN][2],sum[MAXN],tot;
    int stk[MAXN],tp;
    void up(int x) {
        sum[x]=sum[ch[x][0]]^sum[ch[x][1]]^val[x];
    }
    void push_rev(int x) {
        rev[x]^=1;
        swap(ch[x][0],ch[x][1]);
    }
    void down(int x) {
        if(rev[x]) {
            rev[x]=0; 
            push_rev(ch[x][0]);
            push_rev(ch[x][1]);
        }
    }
    int get(int x) {
        return ch[fa[x]][1]==x;
    }
    bool isroot(int x) {
        return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;
    }
    void rotate(int x) {
        int f1=fa[x],f2=fa[f1],id=get(x);
        ch[f1][id]=ch[x][id^1]; fa[ch[f1][id]]=f1;
        if(!isroot(f1)) ch[f2][get(f1)]=x; fa[x]=f2; //!!!!!
        ch[x][id^1]=f1; fa[f1]=x;
        up(f1);
    }
    void splay(int x) {
        tp=0;
        int y=x;
        stk[++tp]=y; //!!!!!
        while(!isroot(y)) stk[++tp]=y=fa[y];
        while(tp) down(stk[tp--]);
        while(!isroot(x)) { //!!!!!
            int f1=fa[x],f2=fa[f1];
            if(!isroot(f1)) {
                if(get(x)==get(f1)) rotate(f1);
                else rotate(x);
            }
            rotate(x);
        }
        up(x);
    }
    void access(int x) {
        for(int y=0;x;y=x,x=fa[x])
            splay(x),ch[x][1]=y,up(x);
    }
    void makeroot(int x) {
        access(x);
        splay(x);
        push_rev(x);
    }
    int findroot(int x) {
        access(x); splay(x);
        while(ch[x][0]) x=ch[x][0];
        splay(x);
        return x;
    }
    void split(int x,int y) {
        makeroot(x);
        access(y);
        splay(y);
    }
    void link(int x,int y) {
        makeroot(x);
        if(findroot(y)!=x) fa[x]=y;
    }
    void cut(int x,int y) {
        makeroot(x);
        if(findroot(y)==x&&fa[y]==x&&!ch[y][0]) { //!!!!!
            fa[y]=ch[x][1]=0;
            up(x);
        }
    }
}tr;
int main() {
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%d",&tr.val[i]);
    for(int i=1;i<=m;i++) {
        int opt,x,y;
        scanf("%d%d%d",&opt,&x,&y);
        switch(opt) {
            case 0: tr.split(x,y); printf("%d
",tr.sum[y]); break;
            case 1: tr.link(x,y); break;
            case 2: tr.cut(x,y); break;
            case 3: tr.makeroot(x); tr.val[x]=y; tr.up(x); break;
        }
    }
    return 0;
}

以上是关于LCT模板坑点总结的主要内容,如果未能解决你的问题,请参考以下文章

模板多标记 LCT

UVa1589 Xiangqi 坑点总结+参考代码

BZOJ2049,2631,3282,1180LCT模板四连A

模板LCT

模板LCT

LCT模板