bzoj3224:普通平衡树

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.每个数的数据范围:[-2e9,2e9]
题解
平衡树的模版题,用来存模版了。
1、Treap
  1 #include<cstdio>
  2 #include<algorithm>
  3 #include<cstring>
  4 #include<cstdlib>
  5 #define maxn 100005
  6 #define inf 1<<29
  7 using namespace std;
  8 int cnt,ret,n,root;
  9 struct treap{int lc,rc,key,pri,siz,val;}a[maxn];
 10 void pushup(int o){a[o].siz=a[a[o].lc].siz+a[a[o].rc].siz+a[o].val;}
 11 void rturn(int &o)
 12 {
 13     int t=a[o].lc;
 14     a[o].lc=a[t].rc;
 15     a[t].rc=o;
 16     a[t].siz=a[o].siz;
 17     pushup(o);
 18     o=t;
 19     return ;
 20 }
 21 void lturn(int &o)
 22 {
 23     int t=a[o].rc;
 24     a[o].rc=a[t].lc;
 25     a[t].lc=o;
 26     a[t].siz=a[o].siz;
 27     pushup(o);
 28     o=t;
 29     return ;
 30 }
 31 void insert(int &o,int x)
 32 {
 33     if(!o)
 34     {
 35         o=++cnt;
 36         a[o]=(treap){0,0,x,rand(),1,1};
 37         return ;
 38     }
 39     ++a[o].siz;
 40     if(x==a[o].key)++a[o].val;
 41     else if(x<a[o].key){insert(a[o].lc,x);if(a[a[o].lc].pri>a[o].pri)rturn(o);}
 42     else{insert(a[o].rc,x);if(a[a[o].rc].pri>a[o].pri)lturn(o);}
 43 }
 44 void del(int &o,int x)
 45 {
 46     if(!o)return ;
 47     if(x==a[o].key)
 48     {
 49         if(a[o].val>1)a[o].val--,a[o].siz--;
 50         else if(!(a[o].lc*a[o].rc))o=a[o].lc+a[o].rc;
 51         else 
 52         {
 53             if(a[a[o].lc].pri>a[a[o].rc].pri){rturn(o);del(o,x);}
 54             else{lturn(o);del(o,x);}
 55         }
 56     }
 57     else if(x<a[o].key){a[o].siz--;del(a[o].lc,x);}
 58     else {a[o].siz--;del(a[o].rc,x);}
 59 }
 60 int que_rank(int o,int x)
 61 {
 62     if(!o)return 0;
 63     if(x<a[o].key)return que_rank(a[o].lc,x);
 64     if(x==a[o].key)return a[a[o].lc].siz+1;
 65     return a[a[o].lc].siz+a[o].val+que_rank(a[o].rc,x);
 66 }
 67 int que_num(int o,int x)
 68 {
 69     if(!o)return 0;
 70     if(x<=a[a[o].lc].siz)return que_num(a[o].lc,x);
 71     if(x<=a[a[o].lc].siz+a[o].val)return a[o].key;
 72     return que_num(a[o].rc,x-a[a[o].lc].siz-a[o].val);
 73 }
 74 void que_pro(int o,int x)
 75 {
 76     if(!o)return ;
 77     if(x<=a[o].key)que_pro(a[o].lc,x);
 78     else {ret=a[o].key;que_pro(a[o].rc,x);}
 79 }
 80 void que_sub(int o,int x)
 81 {
 82     if(!o)return ;
 83     if(x>=a[o].key)que_sub(a[o].rc,x);
 84     else {ret=a[o].key;que_sub(a[o].lc,x);}
 85 }
 86 int main()
 87 {
 88     scanf("%d",&n);
 89     srand(n);
 90     for(int i=1 ; i<=n ; ++i)
 91     {
 92         int a,b;
 93         scanf("%d%d",&a,&b);
 94         if(a==1)insert(root,b);
 95         else if(a==2)del(root,b);
 96         else if(a==3)printf("%d\n",que_rank(root,b));
 97         else if(a==4)printf("%d\n",que_num(root,b));
 98         else if(a==5)
 99         {
100             ret=-inf;
101             que_pro(root,b);
102             printf("%d\n",ret);
103         }
104         else 
105         {
106             ret=inf;
107             que_sub(root,b);
108             printf("%d\n",ret);
109         }
110     }
111     return 0;
112 }

 

posted @ 2017-09-18 23:13  傅judge  阅读(138)  评论(0编辑  收藏  举报