码迷,mamicode.com
首页 > 其他好文 > 详细

LCT模板坑点总结

时间:2019-12-07 21:45:04      阅读:85      评论:0      收藏:0      [点我收藏+]

标签:case   cas   const   clu   pre   cstring   access   get   stream   

#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\n",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模板坑点总结

标签:case   cas   const   clu   pre   cstring   access   get   stream   

原文地址:https://www.cnblogs.com/Gkeng/p/12003058.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!