刚学平衡树,分别用了Splay和fhq-treap交了一遍。

这是Splay的板子,貌似比较短?

Splay

``` cpp
#include
#include
#include
#include

using namespace std;

const int N = 100005, INF = 2e9;

int n;

int nid, root;

int fa[N], ch[N][2];

int val[N];

int sz[N], rep[N];

void update(int x) {

sz[x] = sz[ch[x][0]]+sz[ch[x][1]]+rep[x];

}

void rotate(int x) {

int y = fa[x], z = fa[y];

int d = ch[fa[x]][1]x;

ch[z][ch[fa[y]][1]y] = x; fa[x] = z;

ch[y][d] = ch[x][d^1]; fa[ch[x][d^1]] = y;

ch[x][d^1] = y; fa[y] = x;

update(y); update(x);

}

void splay(int x, int goal) {

for(; fa[x] != goal; rotate(x)) if(fa[fa[x]] != goal)

(ch[fa[x]][0]x)^(ch[fa[fa[x]]][0]fa[x]) ? rotate(x) : rotate(fa[x]);

if(!goal) root = x;

}

void find(int v) {

int u = root;

if(!u) return ;

while(ch[u][val[u]<v] && val[u] != v) u = ch[u][val[u]<v];

splay(u, 0);

}

int findPre(int v) {

find(v);

int u = root;

if(val[u] < v) return u;

u = ch[u][0];

while(ch[u][1]) u = ch[u][1];

return u;

}

int findNxt(int v) {

find(v);

int u = root;

if(val[u] > v) return u;

u = ch[u][1];

while(ch[u][0]) u = ch[u][0];

return u;

}

void insert(int v) {

int u = root, f = 0;

while(u && val[u] != v) f = u, u = ch[u][val[u]<v];

if(u) rep[u]++;

else {

nid++;

fa[nid] = f;

ch[f][val[f]<v] = nid;

val[nid] = v;

sz[nid] = rep[nid] = 1;

u = nid;

}

splay(u, 0);

}

void del(int v) {

int pre = findPre(v), nxt = findNxt(v);

splay(pre, 0); splay(nxt, pre);

int tar = ch[nxt][0];

if(rep[tar] > 1) {

rep[tar]--;

splay(tar, 0);

}

else ch[nxt][0] = 0;

}

int kth(int x) {

if(sz[root] < x) return 0;

int u = root;

while(1) {

int lson = ch[u][0];

if(x <= sz[lson]) u = lson;

else if(x > sz[lson]+rep[u]) x -= sz[lson]+rep[u], u = ch[u][1];

else return val[u];

}

}

int main() {

insert(-(1<<31)+2); //添加两个哨兵节点,防止越界

insert((1<<31)-2);

ios_base::sync_with_stdio(false);

cin.tie(0); cout.tie(0);

cin >> n;

for(int i = 1, c, x; i <= n; i++) {

cin >> c >> x;

if(c == 1) insert(x);

else if(c == 2) del(x);

else if(c == 3) find(x), cout << sz[ch[root][0]] << endl;

else if(c == 4) cout << kth(x+1) << endl;

else if(c == 5) cout << val[findPre(x)] << endl;

else if(c == 6) cout << val[findNxt(x)] << endl;

}

return 0;

}


  1. 这是fhq-treap的板子(为了美观,我已经不能再无脑压行了)
  2. <h3>fhq-treap</h3>
  3. ``` cpp
  4. #include <iostream>
  5. #include <cstring>
  6. #include <algorithm>
  7. #include <ctime>
  8. using namespace std;
  9. const int N = 100005;
  10. int n;
  11. int ch[N][2], val[N], sz[N], rnd[N];
  12. int nid, root;
  13. void update(int x) {
  14. sz[x] = sz[ch[x][0]]+sz[ch[x][1]]+1;
  15. }
  16. int merge(int x, int y) {
  17. if(!x || !y) return x+y;
  18. if(rnd[x] < rnd[y]) {
  19. ch[x][1] = merge(ch[x][1], y);
  20. update(x);
  21. return x;
  22. } else {
  23. ch[y][0] = merge(x, ch[y][0]);
  24. update(y);
  25. return y;
  26. }
  27. }
  28. void split(int cur, int k, int &x, int &y) {
  29. if(!cur) x = y = 0;
  30. else {
  31. if(val[cur] <= k) x = cur, split(ch[cur][1], k, ch[cur][1], y);
  32. else y = cur, split(ch[cur][0], k, x, ch[cur][0]);
  33. update(cur);
  34. }
  35. }
  36. int newNode(int v) {
  37. val[++nid] = v;
  38. sz[nid] = 1;
  39. rnd[nid] = rand();
  40. return nid;
  41. }
  42. void insert(int v) {
  43. int x, y;
  44. split(root, v, x, y);
  45. root = merge(merge(x, newNode(v)), y);
  46. }
  47. void del(int v) {
  48. int x, y, z;
  49. split(root, v, x, z); split(x, v-1, x, y);
  50. y = merge(ch[y][0], ch[y][1]);
  51. root = merge(merge(x, y), z);
  52. }
  53. int rankOf(int v) {
  54. int x, y, ret;
  55. split(root, v-1, x, y);
  56. ret = sz[x]+1;
  57. root = merge(x, y);
  58. return ret;
  59. }
  60. int kth(int src, int x) {
  61. if(sz[src] < x) return 0;
  62. int u = src;
  63. while (1) {
  64. if(x <= sz[ch[u][0]]) u = ch[u][0];
  65. else if(sz[ch[u][0]]+1 == x) return u;
  66. else if(sz[ch[u][0]]+1 < x) x -= sz[ch[u][0]]+1, u = ch[u][1];
  67. }
  68. }
  69. int precursor(int v) { //前驱
  70. int x, y, ret;
  71. split(root, v-1, x, y);
  72. ret = val[kth(x, sz[x])];
  73. root = merge(x, y);
  74. return ret;
  75. }
  76. int successor(int v) { //后继
  77. int x, y, ret;
  78. split(root, v, x, y);
  79. ret = val[kth(y, 1)];
  80. root = merge(x, y);
  81. return ret;
  82. }
  83. int main() {
  84. srand((unsigned)time(NULL));
  85. ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
  86. cin >> n;
  87. for(int i = 1, c, x; i <= n; i++) {
  88. cin >> c >> x;
  89. if(c == 1) insert(x);
  90. else if(c == 2) del(x);
  91. else if(c == 3) cout << rankOf(x) << endl;
  92. else if(c == 4) cout << val[kth(root, x)] << endl;
  93. else if(c == 5) cout << precursor(x) << endl;
  94. else if(c == 6) cout << successor(x) << endl;
  95. }
  96. return 0;
  97. }

洛谷P3369 普通平衡树的更多相关文章

  1. 洛谷P3369普通平衡树(Treap)

    题目传送门 转载自https://www.cnblogs.com/fengzhiyuan/articles/7994428.html,转载请注明出处 Treap 简介 Treap 是一种二叉查找树.它 ...

  2. [洛谷P3369] 普通平衡树 Treap & Splay

    这个就是存一下板子...... 题目传送门 Treap的实现应该是比较正经的. 插入删除前驱后继排名什么的都是平衡树的基本操作. #include<cstdio> #include< ...

  3. 洛谷P3369 【模板】普通平衡树(Treap/SBT)

    洛谷P3369 [模板]普通平衡树(Treap/SBT) 平衡树,一种其妙的数据结构 题目传送门 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入x数 删除 ...

  4. 【洛谷P3369】【模板】普通平衡树题解

    [洛谷P3369][模板]普通平衡树题解 题目链接 题意: 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3 ...

  5. [洛谷P3391] 文艺平衡树 (Splay模板)

    初识splay 学splay有一段时间了,一直没写...... 本题是splay模板题,维护一个1~n的序列,支持区间翻转(比如1 2 3 4 5 6变成1 2 3 6 5 4),最后输出结果序列. ...

  6. 绝对是全网最好的Splay 入门详解——洛谷P3369&BZOJ3224: Tyvj 1728 普通平衡树 包教包会

    平衡树是什么东西想必我就不用说太多了吧. 百度百科: 一个月之前的某天晚上,yuli巨佬为我们初步讲解了Splay,当时接触到了平衡树里的旋转等各种骚操作,感觉非常厉害.而第二天我调Splay的模板竟 ...

  7. BZOJ3223/洛谷P3391 - 文艺平衡树

    BZOJ链接 洛谷链接 题意 模板题啦~2 代码 //文艺平衡树 #include <cstdio> #include <algorithm> using namespace ...

  8. BZOJ3224/洛谷P3391 - 普通平衡树(Splay)

    BZOJ链接 洛谷链接 题意简述 模板题啦~ 代码 //普通平衡树(Splay) #include <cstdio> int const N=1e5+10; int rt,ndCnt; i ...

  9. 洛谷 P3391 文艺平衡树

    题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 --b ...

随机推荐

  1. 数据库CRUD操作以及MyBatis的配置使用

    • 业务字段设计 • 数据库创建 • CRUD操作 • MyBatis集成 • 注解和XML定义 • ViewObject和DateTool • 首页开发     • 业务字段设计 实体: name: ...

  2. Server 2008 R2多用户远程桌面连接授权,解决120天过期问题

    在工作中,我们往往需要远程服务器,经常会遇到以下这两个麻烦事. 一.远程桌面的连接数限制,超出系统就会提示超过连接数. 二.远程桌面连接时,同一个用户不能同时远程2个桌面连接. ----------- ...

  3. SQLServer之删除索引

    使用SSMS数据库管理工具删除索引 使用表设计器删除索引 表设计器可以删除任何类型的索引,本示例演示删除XML辅助索引,删除其他索引步骤相同. 1.连接数据库,选择数据库,展开数据库->选择数据 ...

  4. Error:Cannot run program "svn" (in directory "E:demo\Hello"): CreateProcess error=2,

    file-->settings-->version controller --> subversion

  5. 面向对象_item项目

    详细见老师博客:http://www.cnblogs.com/Eva-J/articles/7351812.html#_label9 __getitem__\__setitem__\__delitem ...

  6. 【Linux基础】查看硬件信息-硬盘

     一.基础知识 1.磁盘分区 磁盘的分区主要分为基本分区(primary partion)和扩充分区(extension partion)两种,基本分区和扩充分区的数目之和不能大于四个.且基本分区可以 ...

  7. 第十届蓝桥杯省赛JavaB组个人题解

    前言 以下的第十届蓝桥杯Java B组省赛的题目题解只是我个人的题解,提供一些解题思路,仅作参考,如有错误,望大家指出,不甚感激,我会及时更改. 试题 A: 组队 ----- 答案:490 [问题描述 ...

  8. Eclipse中的快捷键

    Ctrl+1:快捷修复(数字 1 不是字母 l) 将鼠标悬停到出错区域,按 Ctrl+1,出现快捷修复的菜单, 按上下方向键选择一种修复方式即可. 也可以将光标移动到出错区域,按 F2 + Enter ...

  9. iOS开发基础-UITableView基本属性

    设置 UITableView 中 cell 的背景颜色. 示例1:通过 backgroundView 设置. UIView *view1 = [[UIView alloc] init]; view1. ...

  10. 1 Introduction

    1. Introduction 1.1. License Flowable is distributed under the Apache V2 license. 1.2. Download http ...