题目:

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]

题解:

splay模板题···表示两周没碰键盘手都生了····

代码:

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstdlib>
  4. #include<cmath>
  5. #include<ctime>
  6. #include<cctype>
  7. #include<cstring>
  8. #include<string>
  9. #include<algorithm>
  10. using namespace std;
  11. const int N=;
  12. int root,size[N],son[N][],key[N],cnt[N],tot,father[N];
  13. int a,b,n;
  14. inline void clear(int now)
  15. {
  16. size[now]=son[now][]=son[now][]=key[now]=cnt[now]=father[now]=;
  17. }
  18. inline void update(int now)
  19. {
  20. if(now)
  21. {
  22. size[now]=cnt[now];
  23. if(son[now][]) size[now]+=size[son[now][]];
  24. if(son[now][]) size[now]+=size[son[now][]];
  25. }
  26. }
  27. inline int get(int a)
  28. {
  29. return son[father[a]][]==a;
  30. }
  31. inline void rotate(int now)
  32. {
  33. int fa=father[now],ofa=father[fa],which=get(now);
  34. son[fa][which]=son[now][which^],father[son[fa][which]]=fa;
  35. son[now][which^]=fa,father[fa]=now,father[now]=ofa;
  36. if(ofa) son[ofa][son[ofa][]==fa]=now;
  37. update(fa),update(now);
  38. }
  39. inline void splay(int now)
  40. {
  41. while(father[now])
  42. {
  43. if(father[father[now]]) rotate(get(now)==get(father[now])?father[now]:now);
  44. rotate(now);
  45. }
  46. root=now;
  47. }
  48. inline void insert(int x)
  49. {
  50. int now=root,last=;
  51. while(true)
  52. {
  53. if(!now)
  54. {
  55. now=++tot;size[now]=cnt[now]=;father[now]=last;key[now]=x;
  56. son[last][key[now]>key[last]]=now;update(last);splay(now);
  57. break;
  58. }
  59. if(key[now]==x)
  60. {
  61. cnt[now]++;update(now);update(last);splay(now);
  62. break;
  63. }
  64. last=now;now=son[now][x>key[now]];
  65. }
  66. }
  67. inline int find(int x)
  68. {
  69. int now=root,ans=;
  70. while(true)
  71. {
  72. if(x<key[now]) now=son[now][];
  73. else
  74. {
  75. ans+=size[son[now][]];
  76. if(x==key[now]) {splay(now);return ans+;}
  77. ans+=cnt[now];now=son[now][];
  78. }
  79. }
  80. }
  81. inline int findx(int x)
  82. {
  83. int now=root;
  84. while(true)
  85. {
  86. if(x<=size[son[now][]]) now=son[now][];
  87. else
  88. {
  89. int temp=size[son[now][]]+cnt[now];
  90. if(x<=temp) return key[now];
  91. x-=temp;now=son[now][];
  92. }
  93. }
  94. }
  95. inline int pre()
  96. {
  97. int now=son[root][];
  98. while(son[now][]) now=son[now][];
  99. return now;
  100. }
  101. inline int next()
  102. {
  103. int now=son[root][];
  104. while(son[now][]) now=son[now][];
  105. return now;
  106. }
  107. inline void Delete(int x)
  108. {
  109. int nothing=find(x);
  110. if(cnt[root]>) {cnt[root]--;return;}
  111. else if(!son[root][]&&!son[root][])
  112. {clear(root);root=;return;}
  113. else if(!son[root][])
  114. {int oldroot=root;root=son[root][];father[root]=;clear(oldroot);return;}
  115. else if(!son[root][])
  116. {int oldroot=root;root=son[root][];father[root]=;clear(oldroot);return;}
  117. else
  118. {
  119. int leftbig=pre(),oldroot=root;
  120. splay(leftbig);son[root][]=son[oldroot][];
  121. father[son[root][]]=root;clear(oldroot);
  122. update(root);
  123. return;
  124. }
  125. }
  126. inline int findpre(int x)
  127. {
  128. insert(x);int temp=pre();
  129. Delete(x);return key[temp];
  130. }
  131. inline int findnext(int x)
  132. {
  133. insert(x);int temp=next();
  134. Delete(x);return key[temp];
  135. }
  136. int main()
  137. {
  138. //freopen("a.in","r",stdin);
  139. scanf("%d",&n);
  140. for(int i=;i<=n;i++)
  141. {
  142. scanf("%d%d",&a,&b);
  143. if(a==)
  144. insert(b);
  145. if(a==)
  146. Delete(b);
  147. if(a==)
  148. {
  149. int temp=find(b);
  150. printf("%d\n",temp);
  151. }
  152. if(a==)
  153. {
  154. int temp=findx(b);
  155. printf("%d\n",temp);
  156. }
  157. if(a==)
  158. {
  159. int temp=findpre(b);
  160. printf("%d\n",temp);
  161. }
  162. if(a==)
  163. {
  164. int temp=findnext(b);
  165. printf("%d\n",temp);
  166. }
  167. }
  168. return ;
  169. }

算法复习——splay(bzoj3224)的更多相关文章

  1. 算法复习——splay+启发式合并(bzoj2733-永无乡)

    题目: Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通 ...

  2. C#冒泡算法复习

    C#冒泡算法复习 冒泡算法的意思:每一趟找到一个最小或最大的数放到最后面,比较总数的n-1次(因为比较是2个双双比较的) 第一层循环表示进行比较的次数,总共要比较(数的)-1次 (因为比较是2个双双比 ...

  3. C语言排序算法复习

    排序算法有很多种,这里在复习和分析的基础上,做一个自己的总结: 首先要知道有哪些排序算法,google一下,有云C语言7大经典排序算法(也有8大).主要包括冒泡排序,快速排序,选择排序,插入排序,希尔 ...

  4. KMP算法复习【+继续学习】

    离NOIP还剩12天,本蒟蒻开始准备复习了. 先来个KMP[似乎我并没有写过KMP的blog] KMP KMP算法是解决字符串匹配问题的一个算法,主要是单对单的字符串匹配加速,时间复杂度O(m + n ...

  5. 算法复习周------“动态规划之‘最长公共子序列’”&&《计蒜课》---最长公共子串题解

    问题描述: 这个问题其实很容易理解.就是给你两个序列X={x1,x2,x3......xm} Y={y1,y2,y3......ym},要求找出X和Y的一个最长的公共子序列. 例:Xi={A, B, ...

  6. [算法] 数据结构 splay(伸展树)解析

    前言 splay学了已经很久了,只不过一直没有总结,鸽了好久来写一篇总结. 先介绍 splay:亦称伸展树,为二叉搜索树的一种,部分操作能在 \(O( \log n)\) 内完成,如插入.查找.删除. ...

  7. K-Means聚类和EM算法复习总结

    摘要: 1.算法概述 2.算法推导 3.算法特性及优缺点 4.注意事项 5.实现和具体例子 6.适用场合 内容: 1.算法概述 k-means算法是一种得到最广泛使用的聚类算法. 它是将各个聚类子集内 ...

  8. 通过“回文字算法”复习C++语言。

    一.什么是回文字 给定一个字符串,从前往后读和从后往前读,字符串序列不变.例如,河北省农村信用社的客服电话是“96369”,无论从后往前读,还是从前后往后读,各个字符出现的位置不变. 二.功能实现 ( ...

  9. 算法模板——splay区间反转 2

    实现功能:同splay区间反转 1(基于BZOJ3223 文艺平衡树) 这次改用了一个全新的模板(HansBug:琢磨了我大半天啊有木有),大大简化了程序,同时对于splay的功能也有所完善 这里面没 ...

随机推荐

  1. How to install Eclipse in linux

    http://askubuntu.com/questions/26632/how-to-install-eclipse

  2. 将回车键转换为Tab键

    实现效果: 知识运用: KeyEventArgs类的KeyValue属性 public int KeyValue {get;} //获取KeyDown或KeyUp事件的键盘值 SendKeys类的Se ...

  3. 【转】Intellij Idea识别Java Web项目

    使用maven生成一个Java项目,手动添加相应的web目录WEB_INF,web.xml等,此时idea没有自动识别为web项目,此时编辑web.xml文件会出现一些不该出现的错误,需要做的就是让i ...

  4. PAT (Basic Level) Practise (中文)-1033. 旧键盘打字(20)

    PAT (Basic Level) Practise (中文)-1033. 旧键盘打字(20)  http://www.patest.cn/contests/pat-b-practise/1033 旧 ...

  5. 升级nodejs 与短小的n模块

    要用指令升级nodejs到新版本要先安装n模块 window用不了n模块  可以用 nvm-windows : https://github.com/coreybutler/nvm-windows n ...

  6. OJ 大整数减法

    描述 求两个大的正整数相减的差. 输入 共2行,第1行是被减数a,第2行是减数b(a > b).每个大整数不超过200位,不会有多余的前导零. 输出 一行,即所求的差. 样例输入 9999999 ...

  7. 004 html常用标签

    html常用标签 1.无语义标签 <div></div> <span></span> 2.常用语义标签 <hn></hn> 标题 ...

  8. (10)zabbix item key详解

    1. 灵活的参数 参数位置可用接收任意参数则是灵活的.例如vfs.fs.size[*],”*”星号可以使用任意的参数,例如:vfs.fs.size[/]vfs.fs.size[/opt] 2. Key ...

  9. (1) zabbix进程构成

    进程介绍 zabbix_agentd客户端守护进程,此进程收集客户端数据,例如cpu负载.内存.硬盘使用情况等 zabbix_getzabbix工具,单独使用的命令,通常在server或者proxy端 ...

  10. PHP中文件锁与进程锁的使用区别

    php中文网的一篇文章,收为己用了.源地址: http://www.php.cn/php-weizijiaocheng-376853.html 本篇文章主要介绍了PHP 文件锁与进程锁的使用示例,小编 ...