• 动态树模板


    Link Cut Tree:

    #include<bits/stdc++.h>
    #define L(x) T[(x)].son[0]
    #define R(x) T[(x)].son[1]
    #define fa(x) T[(x)].fa
    using namespace std;
    const int N=300050;
    int stk[N];
    int n,m;
    struct Tree{
        int son[2],fa;
        int val,siz,Xor;
        bool tag;
    }T[N];
    bool isroot(int x){
        return (L(fa(x))==x||R(fa(x))==x)==0;
    }
    void pushup(int x){
        T[x].Xor=T[L(x)].Xor^T[R(x)].Xor^T[x].val;
        return;
    }
    void rev(int x){
        swap(L(x),R(x));
        T[x].tag^=1;
    }
    void pushdown(int x){
        if(T[x].tag){
            if(L(x))rev(L(x));
            if(R(x))rev(R(x));
            T[x].tag=0;
        }
    }
    bool identify(int x){
        return L(fa(x))==x?0:1;
    }
    void connect(int x,int fa,int son){
        fa(x)=fa;
        T[fa].son[son]=x;
    }
    //以下Splay与普通的Splay有若干处不同 
    void rotate(int x){
        int y=fa(x);
        int z=fa(y);
        int zson=identify(y);
        int yson=identify(x);
        int xson=T[x].son[yson^1];
        fa(x)=fa(y);//将x的父亲设成y的父亲:区别1 
        if(!isroot(y))connect(x,z,zson);//判y,转的顺序不同:区别2 
        connect(xson,y,yson);
        connect(y,x,yson^1);
        pushup(y);
        pushup(x);
        return ;
    }
    void splay(int x){//传一个参:区别3
        int tp=0,y=x;
        stk[++tp]=y;
        while(!isroot(y))stk[++tp]=y=fa(y);
        while(tp)pushdown(stk[tp--]);//存路径推标记:区别4 
        while(!isroot(x)){
            int fa=fa(x);
            if(!isroot(fa)){//判y:区别5
                if(identify(x)!=identify(fa)){
                    rotate(x);
                }else{
                    rotate(fa);
                }
            }
            rotate(x);
        }//无换根:区别6
    }
    void access(int x){
        for(int y=0;x;y=x,x=fa(x)){
            splay(x);
            R(x)=y;
            pushup(x);
        }
    }
    void makeroot(int x){
        access(x);
        splay(x);
        rev(x);
    }
    int findroot(int x){
        access(x);
        splay(x);
        while(L(x)){
            pushdown(x);
            x=L(x);
        }
        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)return;
        fa(x)=y;
    }
    void cut(int x,int y){
        makeroot(x);
        if(findroot(y)!=x||fa(y)!=x||L(y))return;
        fa(y)=R(x)=0;
        pushup(x);
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            scanf("%d",&T[i].val);
        }
        for(int i=1;i<=m;i++){
            int opt,x,y;
            scanf("%d%d%d",&opt,&x,&y);
            if(opt==0){
                split(x,y);
                printf("%d
    ",T[y].Xor);
            }else if(opt==1){
                link(x,y);
            }else if(opt==2){
                cut(x,y);
            }else if(opt==3){
                splay(x);
                T[x].val=y;
            }
        }
    } 
    LCT

    其他动态树待补

  • 相关阅读:
    array_count_values源码
    php 编译安装记录
    mysql 安装的过程做个记录
    初识highcharts 库
    php 不重新编译增加新扩展的方法
    备考PMP
    Beyond Compare4破解--写reg脚本删除注册表
    SourceTree 跳过登录
    正则 (?=exp)
    springmvc--处理器的返回参数
  • 原文地址:https://www.cnblogs.com/passione-123456/p/12254028.html
Copyright © 2020-2023  润新知