HYSBZ 3224 Tyvj 1728 普通平衡树

题意:
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)
题解:
就和题目一样,是一个平衡树(无旋Treap)的模板题,详见代码

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=100000+10;
const int Inf=1e9;
typedef pair<int,int> D;
struct Treap{
        int lch,rch;
        int data,sum,size;
        #define L(u) a[u].lch
        #define R(u) a[u].rch
}a[maxn];
int n,cnt,root;
D Split(int,int);
int Merge(int,int);
void Pushup(int);
void Insert(int);
void Delte(int);
int GetRank(int,int);
int Find(int,int);
int GetPre(int,int);
int GetNext(int,int);
int main(){
        // freopen("in.cpp","r",stdin);
        scanf("%d",&n);
        int op,x;
        for(int i=1;i<=n;i++){
                scanf("%d%d",&op,&x);
                if(op==1)Insert(x);
                else if(op==2)Delte(x);
                else if(op==3)printf("%d
",GetRank(root,x));
                else if(op==4)printf("%d
",Find(root,x));
                else if(op==5)printf("%d
",GetPre(root,x));
                else printf("%d
",GetNext(root,x));
        }
        return 0;
}
void Pushup(int u){
        a[u].size=a[L(u)].size+a[R(u)].size+1;
}
D Split(int u,int k){
        if(u==0)return D(0,0);
        D y;
        int num=a[L(u)].size;
        if(num>=k){
                y=Split(a[u].lch,k);
                a[u].lch=y.second;
                Pushup(u);
                y.second=u;
        }else{
                y=Split(a[u].rch,k-num-1);
                a[u].rch=y.first;
                Pushup(u);
                y.first=u;
        }
        return y;
}
int Merge(int A,int B){
        if(A==0)return B;
        if(B==0)return A;
        if(rand()%(a[A].size+a[B].size)<a[A].size){
                a[A].rch=Merge(a[A].rch,B);
                Pushup(A);
                return A;
        }else{
                a[B].lch=Merge(A,a[B].lch);
                Pushup(B);
                return B;
        }
}
int GetRank(int u,int x){
        int ans=0,tmp=Inf;
        while(u){
                if(x==a[u].data)tmp=min(tmp,ans+a[L(u)].size+1);
                if(x>a[u].data)ans+=a[L(u)].size+1,u=a[u].rch;
                else u=a[u].lch;
        }
        if(tmp==Inf)return ans;
        return tmp;
}
int Find(int u,int x){
        while(1){
                if(a[L(u)].size==x-1)return a[u].data;
                if(a[L(u)].size>x-1)u=a[u].lch;
                else x=x-a[L(u)].size-1,u=a[u].rch;
        }
}
int GetPre(int u,int x){
        int ans=-Inf;
        while(u){
                if(a[u].data<x)ans=max(ans,a[u].data),u=a[u].rch;
                else u=a[u].lch;
        }
        return ans;
}
int GetNext(int u,int x){
        int ans=Inf;
        while(u){
                if(a[u].data>x)ans=min(ans,a[u].data),u=a[u].lch;
                else u=a[u].rch;
        }
        return ans;
}
void Insert(int x){
        int k=GetRank(root,x);
        D tmp=Split(root,k);
        a[++cnt].data=x;
        a[cnt].size=1;
        root=Merge(tmp.first,cnt);
        root=Merge(root,tmp.second);
}
void Delte(int x){
        int k=GetRank(root,x);
        D t1=Split(root,k);
        D t2=Split(t1.first,k-1);
        root=Merge(t2.first,t1.second);
}

原文地址:https://www.cnblogs.com/holy-unicorn/p/9510106.html