ccz181078

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::

Description

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

Input

第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)

Output

对于操作3,4,5,6每行输出一个数,表示对应答案

treap维护每个节点的数值和子树大小。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#define clr(a) memset(a,0,sizeof(a))
#define N 100001
int ch[N][2];
int sz[N],a[N];
int v[N];
int p=1,V;
inline void preins(int x){
    v[p]=V=x;
    sz[p]=1;
    a[p]=rand();
}
inline void upd(int x){
    if(x)sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;
}
struct bst{
    int root;
    bst(){
        root=0;
    }
    void insert(){
        if(root)insert(root);
        else root=p++;
    }
    void insert(int&x){
        bool d=V>v[x];
        int&c=ch[x][d];
        if(c)insert(c);
        else c=p++;
        if(a[ch[x][d]]>a[x])rot(x,d);
        upd(x);
    }void rot(int&w,int c){
        int u=ch[w][c];
        ch[w][c]=ch[u][c^1];
        ch[u][c^1]=w;
        upd(w);
        w=u;
        upd(u);
    }
    int lss(int x){
        int w=root,ans=0;
        while(w){
            if(v[w]<x)ans+=sz[ch[w][0]]+1;
            w=ch[w][v[w]<x];
        }
        return ans;
    }
    void del(int&w,int V){
        if(!w)return;
        if(v[w]==V)del(w);
        else del(ch[w][v[w]<V],V);
        upd(w);
    }
    void del(int&w){
        if(ch[w][0]|ch[w][1]){
            bool d=a[ch[w][0]]<a[ch[w][1]];
            int u=ch[w][d];
            rot(w,d);
            del(ch[w][d^1]);
            upd(u);
        }else w=0;
    }
    int prv(int x){
        int w=root,a=-1;
        while(w){
            if(x>v[w])a=v[w];
            w=ch[w][x>v[w]];
        }
        return a;
    }
    int nxt(int x){
        int w=root,a=-1;
        while(w){
            if(x<v[w])a=v[w];
            w=ch[w][x>=v[w]];
        }
        return a;
    }
    int rnkx(int x){
        int w=root,a=sz[ch[w][0]]+1;
        while(a^x){
            if(x<a)w=ch[w][0],a-=sz[ch[w][1]]+1;
            else w=ch[w][1],a+=sz[ch[w][0]]+1;
        }
        return v[w];
    }
};
bst b;
int n,p1,p2;
int main(){
    clr(ch);clr(sz);clr(a);clr(v);
    a[0]=-1;
    scanf("%d",&n);
    while(n--){
        scanf("%d%d",&p1,&p2);
        switch(p1){
            case 1:preins(p2);b.insert();break;
            case 2:b.del(b.root,p2);break;
            case 3:printf("%d\n",b.lss(p2)+1);break;
            case 4:printf("%d\n",b.rnkx(p2));break;
            case 5:printf("%d\n",b.prv(p2));break;
            case 6:printf("%d\n",b.nxt(p2));break;
        }
    }
    return 0;
}

 

posted on 2016-01-22 20:02  nul  阅读(281)  评论(0编辑  收藏  举报