【BZOJ3224】普通平衡树

来源:互联网 发布:如何取消淘宝实拍保护 编辑:程序博客网 时间:2024/04/27 16:25

Description

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

Solution

这是一道练习treap的模板题,经典题,好题,码农题……
都是一些treap的基本,简单操作。
参见treap复习小记

Code

#include<iostream>#include<cmath>#include<cstdio>#include<cstring>#include<algorithm>#define fo(i,a,b) for(i=a;i<=b;i++)using namespace std;const int maxn=100007;int i,j,k,l,n,m,ans,x,num,op;int t[maxn][2];int size[maxn],sum[maxn],key[maxn],sam[maxn],root;void update(int x){    size[x]=size[t[x][0]]+size[t[x][1]]+sam[x];}void rotate(int &x,int z){    int y=t[x][z];    t[x][z]=t[y][1-z];    t[y][1-z]=x;    update(x);update(y);    x=y; } void insert(int &x,int y){    if(!x){        x=++num;size[x]=1;sam[x]=1;        key[x]=rand();sum[x]=y;        return;    }    size[x]++;    if(sum[x]==y)sam[x]++;    else if(y>sum[x]){        insert(t[x][1],y);        if(key[t[x][1]]<key[x])rotate(x,1);    }    else{        insert(t[x][0],y);        if(key[t[x][0]]>key[x])rotate(x,0);    }}void dele(int &x,int y){    if(!x)return;    if(sum[x]==y){        if(sam[x]>1){            sam[x]--;size[x]--;return;        }        if(!(t[x][0]*t[x][1]))x=t[x][0]+t[x][1];        else{            if(key[t[x][0]]<key[t[x][1]])rotate(x,0),dele(x,y);            else rotate(x,1),dele(x,y);        }    }    else if(y>sum[x])size[x]--,dele(t[x][1],y);    else size[x]--,dele(t[x][0],y);}int posnum(int x,int y){    if(!x)return 0;    if(sum[x]==y)return size[t[x][0]]+1;    else if(sum[x]<y)return posnum(t[x][1],y)+sam[x]+size[t[x][0]];    else return posnum(t[x][0],y);}int posrank(int x,int y){    if(!x)return 0;    if(size[t[x][0]]>=y)return posrank(t[x][0],y);    else if(size[t[x][0]]+sam[x]<y)posrank(t[x][1],y-size[t[x][0]]-sam[x]);    else return sum[x];}void pospre(int x,int y){    if(!x)return;    if(sum[x]<y)ans=sum[x],pospre(t[x][1],y);    else pospre(t[x][0],y);    }void possub(int x,int y){    if(!x)return;    if(sum[x]>y)ans=sum[x],possub(t[x][0],y);    else possub(t[x][1],y);    }int main(){    scanf("%d",&n);    fo(i,1,n){        scanf("%d%d",&op,&x);        switch(op){            case 1:insert(root,x);break;            case 2:dele(root,x);break;            case 3:printf("%d\n",posnum(root,x));break;            case 4:printf("%d\n",posrank(root,x));break;            case 5:ans=0;pospre(root,x);printf("%d\n",ans);break;            case 6:ans=0;possub(root,x);printf("%d\n",ans);break;        }    }}
1 0
原创粉丝点击