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.每个数的数据范围:[-1e7,1e7]
  1 #include <iostream>
  2 #include <cstdio>
  3 #include <algorithm>
  4 #include <cstdlib>
  5 using namespace std;
  6 const int MAXN=1000001;
  7 const int INF=1e9;
  8 struct Treap
  9 {
 10     int ch[2],key,tms,size,dat;
 11 }treap[MAXN];
 12 int root,tot;
 13 int T,op,n;
 14 inline int cmp(int x,int tar)
 15 {
 16     if(tar==treap[x].dat) return -1;
 17     return (tar<treap[x].dat?0:1);
 18 }
 19 inline void maintain(int x)
 20 {
 21     treap[x].size=treap[x].tms;
 22     if(treap[x].ch[0]) treap[x].size+=treap[treap[x].ch[0]].size;
 23     if(treap[x].ch[1]) treap[x].size+=treap[treap[x].ch[1]].size;
 24 }
 25 inline void rotate(int &x,int d)
 26 {
 27     int p=treap[x].ch[d^1];
 28     treap[x].ch[d^1]=treap[p].ch[d];
 29     treap[p].ch[d]=x;
 30     maintain(x);
 31     maintain(p);
 32     x=p;
 33 }
 34 void ins(int &x,int tar)
 35 {
 36     if(!x) 
 37     {
 38         tot++;
 39         treap[tot].key=rand();
 40         treap[tot].dat=tar;
 41         treap[tot].tms=1;
 42         treap[tot].size=1;
 43         x=tot;
 44         return;
 45     }
 46     int d=cmp(x,tar);
 47     if(d==-1) treap[x].tms++;
 48     else 
 49     {
 50         ins(treap[x].ch[d],tar);
 51         if(treap[treap[x].ch[d]].key>treap[x].key) rotate(x,d^1);
 52     }
 53     maintain(x);
 54 }
 55 void del(int &x,int tar)
 56 {
 57     int d=cmp(x,tar);
 58     if(d==-1)
 59     {
 60         if(treap[x].tms>1) treap[x].tms--;
 61         else 
 62         {
 63             if(!treap[x].ch[0]&&!treap[x].ch[1]) x=0;
 64             else if(!treap[x].ch[0]&&treap[x].ch[1]) x=treap[x].ch[1];
 65             else if(treap[x].ch[0]&&!treap[x].ch[1]) x=treap[x].ch[0];
 66             else 
 67             {
 68                 int t=(treap[treap[x].ch[0]].key>treap[treap[x].ch[1]].key?1:0);
 69                 rotate(x,t);
 70                 del(treap[x].ch[t],tar);
 71             }
 72         }
 73     }
 74     else del(treap[x].ch[d],tar);
 75     maintain(x);
 76 }
 77 inline int GetPre(int x,int tar)
 78 {
 79     int con=-INF;
 80     while(x)
 81     {
 82         int d=cmp(x,tar);
 83         if(d==-1) x=treap[x].ch[0];
 84         else if(d) 
 85         {
 86             con=max(con,treap[x].dat);
 87             x=treap[x].ch[1];
 88         }
 89         else x=treap[x].ch[0];
 90     }
 91     return con;
 92 }
 93 inline int GetNext(int x,int tar)
 94 {
 95     int con=INF;
 96     while(x)
 97     {
 98         int d=cmp(x,tar);
 99         if(d==-1) x=treap[x].ch[1];
100         else if(d) x=treap[x].ch[1];
101         else
102         {
103             con=min(con,treap[x].dat);
104             x=treap[x].ch[0];
105         }    
106     }
107     return con;
108 }
109 int GetRank(int x,int tar)
110 {
111     int d=cmp(x,tar);
112     if(d==-1) return treap[treap[x].ch[0]].size+1;
113     else if(d) return treap[treap[x].ch[0]].size+treap[x].tms+GetRank(treap[x].ch[1],tar);
114     else return GetRank(treap[x].ch[0],tar);
115 }
116 int GetKth(int x,int k)
117 {
118     if(k<=treap[treap[x].ch[0]].size) return GetKth(treap[x].ch[0],k);
119     k-=treap[treap[x].ch[0]].size+treap[x].tms;
120     if(k<=0) return treap[x].dat;
121     else return GetKth(treap[x].ch[1],k);
122 }
123 int main(int argc, char *argv[])
124 {
125     scanf("%d",&T);
126     for(int i=1;i<=T;i++)
127     {
128         scanf("%d%d",&op,&n);
129         if(op==1) ins(root,n);
130         else if(op==2) del(root,n);
131         else if(op==3) printf("%d\n",GetRank(root,n));
132         else if(op==4) printf("%d\n",GetKth(root,n));
133         else if(op==5) printf("%d\n",GetPre(root,n));
134         else if(op==6) printf("%d\n",GetNext(root,n));
135     }
136     return 0;
137 }

 

posted @ 2016-07-29 20:11  BeyondW  阅读(488)  评论(1编辑  收藏  举报