题目描述
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:

插入x数
删除x数(若有多个相同的数,因只删除一个)
查询x数的排名(排名定义为比当前数小的数的个数+1。若有多个相同的数,因输出最小的排名)
查询排名为x的数
求x的前驱(前驱定义为小于x,且最大的数)
求x的后继(后继定义为大于x,且最小的数)
输入输出格式
输入格式:
第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号( 1≤opt≤6 )

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

输入输出样例
输入样例#1:
10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598
输出样例#1:
106465
84185
492737
说明
时空限制:1000ms,128M

1.n的数据范围: n≤100000
2.每个数的数据范围: [-{10}^7, {10}^7]

--------------------------------------------------------------------------------------

刚学的,不用旋转的TREAP

好写,主要就是split和merge两个操作。

可以实现可持久化。

可以实现区间操作。

据说,比splay要慢

--------------------------------------------------------------------------------------

  1 #include<bits/stdc++.h>
2 using namespace std;
3 const int maxn=1e5+5;
4 const int inf=1e9;
5 struct node
6 {
7 int ch[2],val,rd,siz;
8 }tr[maxn];
9 int n,m,l,r;
10 int tot,root;
11 int newnode(int v)
12 {
13 ++tot;
14 tr[tot].val=v;
15 tr[tot].rd=rand();
16 tr[tot].siz=1;
17 tr[tot].ch[0]=tr[tot].ch[1]=0;
18 return tot;
19 }
20 void update(int x)
21 {
22 tr[x].siz=tr[tr[x].ch[0]].siz+tr[tr[x].ch[1]].siz+1;
23 }
24 int merge(int a,int b)
25 {
26 if(a*b==0)return a+b;
27 if(tr[a].rd<tr[b].rd)
28 {
29 tr[a].ch[1]=merge(tr[a].ch[1],b);
30 update(a);
31 return a;
32 }
33 else
34 {
35 tr[b].ch[0]=merge(a,tr[b].ch[0]);
36 update(b);
37 return b;
38 }
39 }
40 void split(int cur,int k,int &x,int &y)
41 {
42 if(!cur)x=y=0;
43 else
44 {
45 if(tr[cur].val<=k)
46 {
47 x=cur;
48 split(tr[cur].ch[1],k,tr[cur].ch[1],y);
49 }
50 else
51 {
52 y=cur;
53 split(tr[cur].ch[0],k,x,tr[cur].ch[0]);
54 }
55 update(cur);
56 }
57 }
58 void insert(int v)
59 {
60 int x,y;
61 split(root,v,x,y);
62 root=merge(merge(x,newnode(v)),y);
63 }
64 void del(int v)
65 {
66 int x,y,z;
67 split(root,v,x,z);
68 split(x,v-1,x,y);
69 y=merge(tr[y].ch[0],tr[y].ch[1]);
70 root=merge(merge(x,y),z);
71 }
72 void findrank(int v)
73 {
74 int x,y;
75 split(root,v-1,x,y);
76 printf("%d\n",tr[x].siz+1);
77 root=merge(x,y);
78 }
79 int kth(int now,int k)
80 {
81 int cur=now;
82 while(cur)
83 {
84 if(tr[tr[cur].ch[0]].siz+1==k)return tr[cur].val;
85 else if(tr[tr[cur].ch[0]].siz>=k)cur=tr[cur].ch[0];
86 else
87 {
88 k-=tr[tr[cur].ch[0]].siz+1;
89 cur=tr[cur].ch[1];
90 }
91 }
92 return -inf;
93 }
94 void pre(int v)
95 {
96 int x,y;
97 split(root,v-1,x,y);
98 printf("%d\n",kth(x,tr[x].siz));
99 root=merge(x,y);
100 }
101 void suc(int v)
102 {
103 int x,y;
104 split(root,v,x,y);
105 printf("%d\n",kth(y,1));
106 root=merge(x,y);
107 }
108 int main()
109 {
110 srand((unsigned)time(NULL));
111 int n,op,v;
112 scanf("%d",&n);
113 while(n--)
114 {
115 scanf("%d%d",&op,&v);
116 switch(op)
117 {
118 case 1:insert(v);break;
119 case 2:del(v);break;
120 case 3:findrank(v);break;
121 case 4:printf("%d\n",kth(root,v));break;
122 case 5:pre(v);break;
123 case 6:suc(v);break;
124 default:break;
125 }
126 }
127 return 0;
128 }

最新文章

  1. Appium(客户端版)解决每次运行Android,都安装Appium Setting和Unlock的方法
  2. 关于java jni编译javac javah的问题
  3. MySQL 5.7.x 配置教程
  4. zabbix的一些优化参数随笔
  5. snprintf/strncpy/strlcpy速度测试
  6. hadoop-2.5安装与配置
  7. VS2005调试时无法找到调试信息解决方法
  8. [置顶] 手把手教你iOS消息推送证书生成以及Push消息
  9. 【2014 Multi-University Training Contest 3 1002】/【HDU 4888】 Redraw Beautiful Drawings
  10. UserView--第一种方式set去重,基于Spark算子的java代码实现
  11. freemarker导出带图片的word文档
  12. php截取中文字符串无乱码的方法
  13. 用js实现博客打赏功能
  14. 【C++】实现一个简单的单例模式
  15. php php-fpm安装 nginx配置php
  16. 使用 PsPing &amp; PaPing 进行 TCP 端口连通性测试
  17. 关于opcdaauto.dll的注册
  18. springboot深入学习(三)-----docker
  19. 每天一个linux命令-ls命令
  20. bzoj 2601: [Jsoi2011]同分异构体计数

热门文章

  1. @Transient 注解
  2. HBase内存配置及JVM优化
  3. [leetcode]236. Lowest Common Ancestor of a Binary Tree树的最小公共祖先
  4. java: Compilation failed: internal java compiler error
  5. 基于ESP32的智能家居管理系统的设计与实现
  6. ESP8266-01烧录神器,ESP8266-01S烧录程序 ESP-01烧录固件
  7. C# 9 新特性——init only setter
  8. java内部类 之private 属性对其他对象的访问限制
  9. 单细胞分析实录(5): Seurat标准流程
  10. Phoenix-4.14-cdh5.14.2与hbase-1.2.0-cdh5.14.2集成测试