所谓Treap,就是一种二叉查找树,而我们知道二叉查找树,相对来说比较容易形成最坏的链表情况,所以我们有一种数据结构来防止二叉查找树出现最坏情况,那就是Treap。

Treap=tree+heap,Treap就是这样一种既是树又是堆的奇怪的东东。我们每次插入节点时,便随机的给每个节点赋给一个值,我们要求原始数据满足二叉查找树的性质,而随机值要满足堆的性质。

比如下面的一棵树:

首先我们知道各个节点的“优先级”是采用随机数的方法,那么就存在一个问题,当我们插入一个节点后,优先级不满足“堆定义"的。那么我们就要旋转这课树。

①: 左左情况旋转

②: 右右情况旋转

好在我们写一个旋转函数就可以同时维护左旋和右旋了:

  1. void play(Treap* &rr,int d){
  2. Treap *k=rr->ro[d^];
  3. rr->ro[d^]=k->ro[d];//ro[0]是左孩子,ro[1]是右孩子
  4. k->ro[d]=rr;
  5. rr->rub();//rub()函数的作用是重新统计该子树的大小
  6. k->rub();//必须先rr再k,因为现在rr是k的孩子
  7. rr=k;
  8. }

那么我们就可以刷水题了:(洛谷-普通平衡树)

  1. #include<bits/stdc++.h>
  2. #define sight(c) ('0'<=c&&c<='9')
  3. #define RR NULL
  4. #define inf 1<<29
  5. #define random rrsbRRsb
  6. using namespace std;
  7. inline int random(){
  8. static int seed=;
  9. return seed=int(seed*48271LL%);
  10. }
  11. struct Treap{
  12. int key,rap,siz;
  13. Treap *ro[];
  14. Treap(int k){
  15. siz=;
  16. key=k;
  17. rap=random();
  18. ro[]=ro[]=RR;
  19. }
  20. inline void rub() {
  21. siz=;
  22. if (ro[]!=RR) siz+=ro[]->siz;
  23. if (ro[]!=RR) siz+=ro[]->siz;
  24. }
  25. inline int cop(int x){
  26. if (x==key) return -;
  27. return x<key?:;
  28. }
  29. };
  30. inline void read(int &x) {
  31. static char c; static int b;
  32. for (b=,c=getchar();!sight(c);c=getchar()) if (c=='-') b=-;
  33. for (x=;sight(c);c=getchar()) x=x*+c-;
  34. x*=b;
  35. }
  36. void play(Treap* &rr,int d){
  37. Treap *k=rr->ro[d^];
  38. rr->ro[d^]=k->ro[d];
  39. k->ro[d]=rr;
  40. rr->rub();
  41. k->rub();
  42. rr=k;
  43. }
  44. void Insert(Treap* &rr,int x){
  45. if (rr==RR) rr=new Treap(x);
  46. else {
  47. int d=x < rr->key?:;
  48. Insert(rr->ro[d],x);
  49. if (rr->ro[d]->rap > rr->rap)
  50. play(rr,d^);
  51. }
  52. rr->rub();
  53. }
  54. bool Find(Treap *p,int x){
  55. while(p!=RR) {
  56. int d=p->cop(x);
  57. if (d==-) return true;
  58. p=p->ro[d];
  59. }
  60. return false;
  61. }
  62. void Delete(Treap* &t,int x){
  63. int d=t->cop(x);
  64. if (d==-) {
  65. Treap *tmp=t;
  66. if (t->ro[]==RR) {
  67. t=t->ro[];
  68. delete tmp;
  69. tmp=RR;
  70. } else if (t->ro[]==RR) {
  71. t=t->ro[];
  72. delete tmp;
  73. tmp=RR;
  74. } else {
  75. int k=t->ro[]->rap<t->ro[]->rap?:;
  76. play(t,k);
  77. Delete(t->ro[k],x);
  78. }
  79. }
  80. else Delete(t->ro[d],x);
  81. if (t!=RR) t->rub();
  82. }
  83. int Kth(Treap *t,int k){
  84. int cm=;
  85. if (t->ro[]) cm=t->ro[]->siz;
  86. cm++;
  87. if (cm==k)
  88. return t->key;
  89. if (cm>k) return Kth(t->ro[],k);
  90. return Kth(t->ro[],k-cm);
  91. }
  92. int Rank(Treap *t,int k){
  93. int r;
  94. if (!t) return inf;
  95. if (t->ro[]==RR)
  96. r=;else r=t->ro[]->siz;
  97. if(k==t->key) return min(r+,Rank(t->ro[],k));
  98. if(k<t->key)
  99. return Rank(t->ro[],k);
  100. return r++Rank(t->ro[],k);
  101. }
  102. int Pre(Treap *t,int k){
  103. if (!t) return -inf;
  104. if (k>t->key) return max(t->key,Pre(t->ro[],k));
  105. return Pre(t->ro[],k);
  106. }
  107. int Sub(Treap *t,int k){
  108. if (!t) return inf;
  109. if (k<t->key) return min(t->key,Sub(t->ro[],k));
  110. return Sub(t->ro[],k);
  111. }
  112. int n,op,x;
  113. int main () {
  114. freopen("a.in","r",stdin);
  115. read(n);
  116. Treap* root=RR;
  117. while (n--) {
  118. read(op); read(x);
  119. switch(op){
  120. case :Insert(root,x);break;
  121. case :Delete(root,x);break;
  122. case :printf("%d\n",Rank(root,x));break;
  123. case :printf("%d\n",Kth(root,x));break;
  124. case :printf("%d\n",Pre(root,x));break;
  125. case :printf("%d\n",Sub(root,x));break;
  126. }
  127. // cout<<op<<endl;
  128. }
  129. return ;
  130. }

朴素的treap的更多相关文章

  1. 无旋Treap - BZOJ1014火星人 & 可持久化版文艺平衡树

    !前置技能&概念! 二叉搜索树 一棵二叉树,对于任意子树,满足左子树中的任意节点对应元素小于根的对应元素,右子树中的任意节点对应元素大于根对应元素.换言之,就是满足中序遍历为依次访问节点对应元 ...

  2. BZOJ 3262(Treap+树状数组)

    题面 传送门 分析 分三维考虑 对第一维,直接排序 对第二维和第三维,我们这样考虑 朴素的方法是建k棵Treap,第i棵Treap里存第二维值为k的第三维数值 每次查询一组(a,b,c),只要在1~b ...

  3. fhq treap最终模板

    新学习了fhq treap,厉害了 先贴个神犇的版, from memphis /* Treap[Merge,Split] by Memphis */ #include<cstdio> # ...

  4. BZOJ 1691: [Usaco2007 Dec]挑剔的美食家 [treap 贪心]

    1691: [Usaco2007 Dec]挑剔的美食家 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 786  Solved: 391[Submit][S ...

  5. BZOJ 1862: [Zjoi2006]GameZ游戏排名系统 [treap hash]

    1862: [Zjoi2006]GameZ游戏排名系统 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1318  Solved: 498[Submit][ ...

  6. 非旋treap模板

    bzoj3580 非旋转treap 在大神教导下发现split一段区间时先split右边再split左边比较好写 #include <cstdio> #include <cstdli ...

  7. 朴素贝叶斯算法下的情感分析——C#编程实现

    这篇文章做了什么 朴素贝叶斯算法是机器学习中非常重要的分类算法,用途十分广泛,如垃圾邮件处理等.而情感分析(Sentiment Analysis)是自然语言处理(Natural Language Pr ...

  8. 朴素贝叶斯(NB)复习总结

    摘要: 1.算法概述 2.算法推导 3.算法特性及优缺点 4.注意事项 5.实现和具体例子 6.适用场合 内容: 1.算法概述 贝叶斯分类算法是统计学的一种分类方法,其分类原理就是利用贝叶斯公式根据某 ...

  9. scikit-learn 朴素贝叶斯类库使用小结

    之前在朴素贝叶斯算法原理小结这篇文章中,对朴素贝叶斯分类算法的原理做了一个总结.这里我们就从实战的角度来看朴素贝叶斯类库.重点讲述scikit-learn 朴素贝叶斯类库的使用要点和参数选择. 1. ...

随机推荐

  1. php 将pdf转成图片且将图片拼接

    说明: 1.pdf转图片通过安装php扩展imagick实现. 2.由于windows扩展安装的一系列问题,建议在linux环境开发,windows大伙可以尝试安装. 3.为Centos 安装Imag ...

  2. linux系统下安装配置解压版的MySQL数据库

    一.解压文件到当前目录 命令:tar -zxvf mysql....tar.gz 二.移动解压完成的文件夹到目标目录并更名mysql 命令:mv mysql-版本号 /usr/local/mysql ...

  3. 《图解Spark:核心技术与案例实战》作者经验谈

    1,看您有维护博客,还利用业余时间著书,在技术输出.自我提升以及本职工作的时间利用上您有没有什么心得和大家分享?(也可以包含一些您写书的小故事.)回答:在工作之余能够写博客.著书主要对技术的坚持和热爱 ...

  4. 微信小程序语音与讯飞语音识别接口(Java)

    项目需求,需要使用讯飞的语音识别接口,将微信小程序上传的录音文件识别成文字返回 而微信小程序上传的文件格式是silk的,而讯飞接口能识别wav 格式的文件,所以需要将小程序上传的silk文件转成wav ...

  5. Mysql的管理及使用

    第1章 Mysql的管理 1.1 连接管理mysql mysql[options] #Linux或UNIX shell提示符(终端窗口) mysql --help #查看帮助信息 mysql --ve ...

  6. And【sql语句之为何用and一个字段两个值得不到表中的数据】

    一.[一个表的一个字段的多个条件用and连接] 用and是查不到值的, and是多个条件同时成立, 也就是一个字段是不能同时等于两个值的. '; 二[相同两个表的两个相同字段的查询用and连接] '; ...

  7. x86 处理器开机顺序

    无论是千万行的linux ,还是百万行的uefi ,或者百十行的app, 它都有一个主线.应用程序是main() 函数里面全部函数运行完,程序结束.这里main() 做为程序的起点,uefi 能够觉得 ...

  8. Android setContentView方法解析(一)

    在Activity的生命周期onCreate中.我们一般都习惯性的调用setContentView(int layoutResID)方法,把布局文件载入到页面上来.以下我们就来通过源代码一步步的分析怎 ...

  9. Android之——ListView优化

    转载请注明出处:http://blog.csdn.net/l1028386804/article/details/47209253 作为client.其最基本的任务就是最直观的和用户交互.从serve ...

  10. ajax接收json

    l 什么是json? l Json和xml比较 l Ajax如何使用JSON l Ajax接收json响应案例 什么是json? JSON (JavaScript Object Notation) 是 ...