结构体Splay平衡树板子

普通平衡树:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
const int INF = 1e9;

class Splay{
#define root t[0].son[1]
private:
    struct node{
        int son[2];
        int val,father;
        int size,cnt;
    }t[maxn];
    int n,tot;
    
    void pushup(int x){
        if(x)t[x].size=t[x].cnt+t[t[x].son[0]].size+t[t[x].son[1]].size;
    }
    int identfy(int x){
        return t[t[x].father].son[1]==x;
    }
    void connect(int son,int father,int lr){
        t[son].father=father;
        t[father].son[lr]=son;
    }
    void rotate(int x){
        int f=t[x].father,ff=t[f].father;
        int fs=identfy(x),ffs=identfy(f);
        int temp=t[x].son[fs^1];
        connect(temp,f,fs);
        connect(f,x,fs^1);
        connect(x,ff,ffs);
        pushup(f);pushup(x);
    }
    void splay(int at,int to){
        to=t[to].father;
        while(t[at].father!=to){
            int up=t[at].father;
            if(t[up].father==to)rotate(at);
            else if(identfy(at)==identfy(up)){
                rotate(up);
                rotate(at);
            }else{
                rotate(at);
                rotate(at);
            }
        }
    }
    int create(int val,int father){
        tot++;
        t[tot].val=val;
        t[tot].father=father;
        t[tot].size=t[tot].cnt=1;
        return tot;
    }
    void destroy(int x){
        t[x].son[0]=t[x].son[1]=t[x].val=t[x].father=t[x].size=t[x].cnt=0;
        if(x==tot)tot--;
    }
public:
    int getroot(){return root;}
    int find(int val){
        int now=root;
        while(1){
            if(!now)return 0;
            if(t[now].val==val){
                splay(now,root);
                return now;
            }
            now=t[now].val>val?t[now].son[0]:t[now].son[1];
        }
    }
    int build(int val){
        n++;
        if(!tot){
            root=1;
            create(val,0);
            return 0;
        }else{
            int now=root;
            while(1){
                t[now].size++;
                if(t[now].val==val){
                    t[now].cnt++;
                    return now;
                }
                int nex=t[now].val>val?0:1;
                if(!t[now].son[nex]){
                    create(val,now);
                    t[now].son[nex]=tot;
                    return tot;
                }
                now=t[now].son[nex];
            }
        }
    }
    void push(int val){
        int add=build(val);
        splay(add,root);
    }
    void pop(int val){
        int pos=find(val);
        if(!pos)return ;
        n--;
        if(t[pos].cnt>1){
            t[pos].cnt--;
            t[pos].size--;
            return;
        }
        if(!t[pos].son[0]){
            root=t[pos].son[1];
            t[root].father=0;
        }else if(!t[pos].son[1]){
            root=t[pos].son[0];
            t[root].father=0;
        }else{
            int pre=t[pos].son[0];
            while(t[pre].son[1])pre=t[pre].son[1];
            splay(pre,t[pos].son[0]);
            int temp=t[pos].son[1];
            connect(temp,pre,1);
            connect(pre,0,1);//该树的超级根是t[0].son[1]
            pushup(pre);
        }
        destroy(pos);
    }
    int rank(int val){
        int res=0,now=root;
        while(now){
            if(t[now].val==val){
                int temp=res+t[t[now].son[0]].size+1;
                splay(now,root);
                return temp;
            }
            if(t[now].val>val)now=t[now].son[0];
            else{
                res+=t[t[now].son[0]].size+t[now].cnt;
                now=t[now].son[1];
            }
        }
        return 0;
    }
    int val(int rank){
        if(rank>n)return -INF;
        int now=root;
        while(now){
            if(t[t[now].son[0]].size>=rank)now=t[now].son[0];
            else if(t[t[now].son[0]].size+t[now].cnt>=rank){
                splay(now,root);
                return t[now].val;
            }else{
                rank-=t[t[now].son[0]].size+t[now].cnt;
                now=t[now].son[1];
            }
        }
    }
    int lower(int val){
        int now=root,res=-INF;
        while(now){
            if(t[now].val<val&&t[now].val>res)res=t[now].val;
            if(val>t[now].val)now=t[now].son[1];
            else now=t[now].son[0];
        }
        return res;
    }
    int upper(int val){
        int now=root,res=INF;
        while(now){
            if(t[now].val>val&&t[now].val<res)res=t[now].val;
            if(val<t[now].val)now=t[now].son[0];
            else now=t[now].son[1];
        }
        return res;
    }
    void print(int x){//调试
        if(!x)return;
        print(t[x].son[0]);
        printf("%d ",t[x].val);
        print(t[x].son[1]);
    }
#undef root
};
Splay T;
int m,opt,x;

int main(){
    T.push(-INF);T.push(INF);
    scanf("%d",&m);
    for(int i=1;i<=m;i++){
        scanf("%d%d",&opt,&x);
        if(opt==1)T.push(x);
        if(opt==2)T.pop(x);
        if(opt==3)printf("%d\n",T.rank(x)-1);
        if(opt==4)printf("%d\n",T.val(x+1));
        if(opt==5)printf("%d\n",T.lower(x));
        if(opt==6)printf("%d\n",T.upper(x));
        // printf("\ntexting:");
        // T.print(T.getroot());
        // printf("\n\n");
    }
    return 0;
}
View Code

 文艺平衡树:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
const int INF = 1e9;

struct Splay{
    int son[2];
    int val,father;
    int size,cnt;
    int mark;
}t[maxn];
int a[maxn];
int tot,root;
int n,m,l,r;

void pushup(int x){
    if(x){
        t[x].size=t[x].cnt;
        if(t[x].son[0])t[x].size+=t[t[x].son[0]].size;
        if(t[x].son[1])t[x].size+=t[t[x].son[1]].size;
    }
}
void pushdown(int x){
    if(x&&t[x].mark){
        t[t[x].son[0]].mark^=1;
        t[t[x].son[1]].mark^=1;
        swap(t[x].son[0],t[x].son[1]);
        t[x].mark=0;
    }
}
int which(int x){return t[t[x].father].son[1]==x;}
void connect(int son,int father,int lr){
    if(father)t[father].son[lr]=son;
    t[son].father=father;
}
void rotate(int x){
    int f=t[x].father,ff=t[f].father;
    int fs=which(x),ffs=which(f);
    int temp=t[x].son[fs^1];
    pushdown(x);pushdown(f);
    connect(temp,f,fs);
    connect(f,x,fs^1);
    connect(x,ff,ffs);
    pushup(f);pushup(x);
}
void splay(int at,int to){
    for(int up;(up=t[at].father)!=to;rotate(at)){
        if(t[up].father!=to){
            rotate(which(at)==which(up)?up:at);
        }
    }
    if(!to)root=at;
}
int build(int l,int r,int father){
    if(l>r)return 0;
    int mid=(l+r)>>1;
    int now=++tot;
    t[now].father=father;
    t[now].val=a[mid];
    t[now].cnt++;t[now].size++;
    t[now].son[0]=build(l,mid-1,now);
    t[now].son[1]=build(mid+1,r,now);
    pushup(now);
    return now;
}
int find(int rk){
    int now=root;
    while(1){
        pushdown(now);
        if(t[t[now].son[0]].size>=rk)now=t[now].son[0];
        else{
            rk-=t[t[now].son[0]].size+1;
            if(!rk)return now;
            now=t[now].son[1]; 
        }
    }
}
void mark(int x,int y){
    int l=x-1,r=y+1;
    l=find(l),r=find(r);
    splay(l,0);
    splay(r,l);
    int pos=t[root].son[1];
    pos=t[pos].son[0];
    t[pos].mark^=1;
}
void print(int x){
    pushdown(x);
    if(t[x].son[0])print(t[x].son[0]);
    if(t[x].val!=INF&&t[x].val!=-INF)
        printf("%d ",t[x].val);
    if(t[x].son[1])print(t[x].son[1]);
}
int main(){
    scanf("%d%d",&n,&m);
    a[1]=-INF;a[n+2]=INF;
    for(int i=2;i<=n+1;i++)
        a[i]=i-1;
    root=build(1,n+2,0);
    while(m--){
        scanf("%d%d",&l,&r);
        mark(l+1,r+1);
    }
    print(root);
    return 0;
}
View Code

 

posted @ 2020-12-28 19:57  _Famiglistimo  阅读(124)  评论(0编辑  收藏  举报