普通平衡树(板子)

#include<bits/stdc++.h>
#define val(rt) t[rt].val
#define dat(rt) t[rt].dat
#define cnt(rt) t[rt].cnt
#define size(rt) t[rt].size
#define l(rt) t[rt].l
#define r(rt) t[rt].r
using namespace std;
const int N = 1e5+5; 
const int INF = 1e9;

struct Treap{
    int l,r;
    int val,dat;
    int cnt,size;
}t[N];
int root,tot;
int n,opt,x;

int New(int val){
    val(++tot)=val;
    dat(tot)=rand();
    cnt(tot)=size(tot)=1;
    return tot;
}

void Pushup(int p){
    size(p)=size(l(p))+size(r(p))+cnt(p);
    return;    
}

void Build(){
    root=New(-INF);
    r(1)=New(INF);
    Pushup(root);
    return;
}

void Zuo(int &p){
    int q=r(p);
    r(p)=l(q);
    l(q)=p;p=q;
    Pushup(l(p));
    Pushup(p);
}

void You(int &p){
    int q=l(p);
    l(p)=r(q);
    r(q)=p;p=q;
    Pushup(r(p));
    Pushup(p);
}

void Insert(int &p,int val){
    if(!p){
        p=New(val);
        return ;
    }
    if(val(p)==val)cnt(p)++;
    else{
        if(val<val(p)){
            Insert(l(p),val);
            if(dat(l(p))>dat(p))You(p);
        }else{
            Insert(r(p),val);
            if(dat(r(p))>dat(p))Zuo(p);
        }
    }
    Pushup(p);
}

void Delete(int &p,int val){
    if(!p)return ;
    if(val(p)==val){
        if(cnt(p)>1){
            cnt(p)--;
            Pushup(p);
            return;
        }
        if(l(p)||r(p)){
            if(!r(p)||dat(l(p))>dat(r(p))){
                You(p);
                Delete(r(p),val);
            }
            else{
                Zuo(p);
                Delete(l(p),val);
            }
            Pushup(p);
        }
        else p=0;
        return ;
    }
    val<val(p)?Delete(l(p),val):Delete(r(p),val);
    Pushup(p);
    return;
}

int Rank(int p,int val){
    if(!p)return -2;
    if(val==val(p))return size(l(p))+1;
    if(val<val(p))return Rank(l(p),val);
    else return size(l(p))+cnt(p)+Rank(r(p),val);
}

int Val(int p,int rank){
    if(!p)return INF;
    if(size(l(p))>=rank)return Val(l(p),rank);
    if(size(l(p))+cnt(p)>=rank)return val(p);
    else return Val(r(p),rank-size(l(p))-cnt(p));
}

int Pre(int val){
    int p=root,res;
    while(p){
        if(val(p)<val)
            res=val(p),p=r(p);
        else p=l(p); 
    }
    return res;
}

int Next(int val){
    int p=root,res;
    while(p){
        if(val(p)>val)
            res=val(p),p=l(p);
        else p=r(p); 
    }
    return res;
}

int main(){
    scanf("%d",&n);
    Build();
    while(n--){
        scanf("%d%d",&opt,&x);
        if(opt==1)Insert(root,x);
        if(opt==2)Delete(root,x);
        if(opt==3)printf("%d\n",Rank(root,x)-1);
        if(opt==4)printf("%d\n",Val(root,x+1));
        if(opt==5)printf("%d\n",Pre(x));
        if(opt==6)printf("%d\n",Next(x));
    }
    return 0;
}

 

posted @ 2020-11-24 22:22  _Famiglistimo  阅读(140)  评论(0编辑  收藏  举报