bzoj3224 treap多种操作

来源:互联网 发布:java有返回值的方法 编辑:程序博客网 时间:2024/06/16 13:33

3224: Tyvj 1728 普通平衡树

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 3314  Solved: 1343
[Submit][Status][Discuss]

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每行输出一个数,表示对应答案

Sample Input

10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598

Sample Output

106465
84185
492737

HINT

1.n的数据范围:n<=100000

2.每个数的数据范围:[-1e7,1e7]

写Treap老是要出这样那样的问题,有些细节真不好考虑,真想写一个健壮的Treap啊,可惜能力不够啊。

#include<cstdio>#include<iostream>#include<cstring>#include<cstdlib>using namespace std;struct treap{    int l,r,v,s,d,w;}tr[100010];int root,sz,ans;void update(int &k){    tr[k].s=tr[tr[k].l].s+tr[tr[k].r].s+tr[k].w;}void rturn(int &k){    int t=tr[k].l;    tr[k].l=tr[t].r;    tr[t].r=k;    tr[t].s=tr[k].s;    update(k);    k=t;}void lturn(int &k){    int t=tr[k].r;    tr[k].r=tr[t].l;    tr[t].l=k;    tr[t].s=tr[k].s;    update(k);    k=t;}void insert(int &k,int x){    if(!k){        k=++sz;        tr[k].s=tr[k].w=1;        tr[k].v=x;        tr[k].d=rand();        return;    }    tr[k].s++;    if(tr[k].v==x) tr[k].w++;    else if(tr[k].v<x){        insert(tr[k].r,x);        if(tr[tr[k].r].d<tr[k].d) lturn(k);    }    else{        insert(tr[k].l,x);        if(tr[tr[k].l].d<tr[k].d) rturn(k);    }}void del(int &k,int x){    if(!k) return;    if(tr[k].v==x){        if(tr[k].w>1){            tr[k].w--;            tr[k].s--;            return;        }        if(tr[k].l*tr[k].r==0){            k=tr[k].l+tr[k].r;            return;        }        if(tr[tr[k].l].d<tr[tr[k].r].d){            rturn(k);            del(tr[k].r,x);        }        else{            lturn(k);            del(tr[k].l,x);        }    }    else if(x>tr[k].v) del(tr[k].r,x);    else del(tr[k].l,x);    update(k);}int query_rank(int k,int x){    if(!k) return 0;    if(tr[k].v==x) return tr[tr[k].l].s+1;    if(x<=tr[k].v) return query_rank(tr[k].l,x);    return tr[tr[k].l].s+tr[k].w+query_rank(tr[k].r,x);}int query_val(int k,int x){    if(!k) return k;    if(x<=tr[tr[k].l].s) return query_val(tr[k].l,x);    if(x<=tr[tr[k].l].s+tr[k].w) return tr[k].v;    return query_val(tr[k].r,x-tr[tr[k].l].s-tr[k].w);}void pre(int k,int x){    if(!k) return;    if(tr[k].v<x){        ans=tr[k].v;pre(tr[k].r,x);    }    else pre(tr[k].l,x);}void suc(int k,int x){    if(!k) return;    if(tr[k].v>x){        ans=tr[k].v;suc(tr[k].l,x);    }    else suc(tr[k].r,x);}void print(int k){    if(!k) return;    print(tr[k].l);    printf("%d ",tr[k].v);    print(tr[k].r);}int main(){    int n,op,x;    scanf("%d",&n);    for(int i=0;i<n;i++){        scanf("%d%d",&op,&x);        switch(op){            case 1:insert(root,x);break;            case 2:del(root,x);break;            case 3:printf("%d\n",query_rank(root,x));break;            case 4:printf("%d\n",query_val(root,x));break;            case 5:pre(root,x);printf("%d\n",ans);break;            case 6:suc(root,x);printf("%d\n",ans);break;        }    }return 0;}



0 0
原创粉丝点击