Tyvj 1728 普通平衡树

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]
用的非旋转treap
这种treap只有两种操作:
merge(root1,root2)和split(root,k)
分别表示合并两颗treap和分割一个treap的前k个节点
其他操作都通过这两个实现
这样不用旋转,就可以持久化
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<algorithm>
  4 #include<cstring>
  5 using namespace std;
  6 struct Treap
  7 {
  8   Treap *l,*r;
  9   int val,size,lev;
 10 }S[200001],*pos=S,*root;
 11 int n;
 12 typedef pair<Treap*,Treap*> Droot;
 13 void NewNode(Treap* &r,int val)
 14 {
 15   r=++pos;
 16   r->val=val;
 17   r->lev=rand();
 18   r->size=1;
 19   r->l=r->r=0;
 20 }
 21 int getsize(Treap* x)
 22 {
 23   if (!x) return 0;
 24   else return x->size;
 25 }
 26 void updata(Treap* x)
 27 {
 28   x->size=1;
 29   if (x->l) x->size+=x->l->size;
 30   if (x->r) x->size+=x->r->size;
 31 }
 32 Treap *merge(Treap *A,Treap *B)
 33 {
 34   if (!A) return B;
 35   if (!B) return A;
 36   if (A->lev<B->lev)
 37     {
 38       A->r=merge(A->r,B);
 39       updata(A);
 40       return A;
 41     }
 42   else 
 43     {
 44       B->l=merge(A,B->l);
 45       updata(B);
 46       return B;
 47     }
 48 }
 49 Droot split(Treap *x,int k)
 50 {
 51   if (!x) return Droot(0,0);
 52   Droot y;
 53   if (getsize(x->l)>=k)
 54     {
 55       y=split(x->l,k);
 56       x->l=y.second;
 57       updata(x);
 58       y.second=x;
 59     }
 60   else 
 61     {
 62       y=split(x->r,k-getsize(x->l)-1);
 63       x->r=y.first;
 64       updata(x);
 65       y.first=x;
 66     }
 67   return y;
 68 }
 69 int findkth(int k)
 70 {
 71   Droot x=split(root,k-1);
 72   Droot y=split(x.second,1);
 73   Treap* ans=y.first;
 74   root=merge(merge(x.first,ans),y.second);
 75   if (ans==0) return 0;
 76   return ans->val;
 77 }
 78 int getkth(Treap* x,int val)
 79 {
 80   if (x==0) return 0;
 81   if (val<=x->val)
 82     return getkth(x->l,val);
 83   else return getkth(x->r,val)+getsize(x->l)+1;
 84 }
 85 void insert(int val)
 86 {
 87   int k=getkth(root,val);
 88   Droot x=split(root,k);
 89   Treap *a;
 90   NewNode(a,val);
 91   root=merge(merge(x.first,a),x.second);
 92 }
 93 int del(int val)
 94 {
 95   int k=getkth(root,val);
 96   Droot x=split(root,k);
 97   Droot y=split(x.second,1);
 98   Treap* ans=y.first;
 99   root=merge(x.first,y.second);
100 }
101 int main()
102 {int opt,x;
103   cin>>n;
104   while (n--)
105     {
106       scanf("%d%d",&opt,&x);
107       if (opt==1) 
108     insert(x);
109       else if (opt==2)
110     del(x);
111       else if (opt==3)
112         printf("%d\n",getkth(root,x)+1);
113       else if (opt==4)
114     printf("%d\n",findkth(x));
115       else if (opt==5)
116     printf("%d\n",findkth(getkth(root,x)));
117       else if (opt==6)
118     printf("%d\n",findkth(getkth(root,x+1)+1));
119     }
120 }

 

posted @ 2017-10-06 09:56  Z-Y-Y-S  阅读(325)  评论(0编辑  收藏  举报