借鉴   模板    讲解

模板题

 

看了一上午才看明白,Treap = Tree + Heap,是棵弱平衡树。

一棵树同时具有二叉搜索树的性质和堆的性质,可以完成二叉搜索树和堆的操作。

 

有人曰:

Treap代码量小,速度较快

不能分裂合并,可以可持久化

挺好的东西。

于是我就学了。

 

可完成的操作:1.插入x

       2.删除x数(若有多个相同的数,因只删除一个)

       3.查询x数的排名(若有多个相同的数,因输出最小的排名)

       4.查询排名为x的数

       5.求x的前驱(前驱定义为小于x,且最大的数)

       6.求x的后继(后继定义为大于x,且最小的数)

 

说明:

son[k][0] 表示 k 的左儿子, son[k][1] 表示 k 的右儿子
size[k] 表示以 k 为根的子树的节点数
w[k] 表示节点 k 的权值
rnd[k] 表示节点 k 的优先级
g[k] 表示节点 k 的个数(有可能有重复的)

 

0.旋转

最关键的操作,运用了二进制优化,使左旋和右旋代码合并。

【模板】Treap

给张左旋右旋的图,可以通过这张图来推出左旋右旋代码。(来自百度百科)

 1 //通过旋转来维护小根堆 
 2 //因为通过旋转根是会变的,所以得加 &  
 3 // x 为 0 是 右旋,x 为 1 是 左旋
 4 //但是不必知道是左旋还是右旋
 5 //只知道旋转一个节点的孩子就相当于把这个孩子旋转到父亲上 
 6 void turn(int &k, int x)
 7 {
 8     //位运算优化 ^ 可表示兄弟节点, 使得左旋和右旋合并 
 9     int t = son[k][x];
10     son[k][x] = son[t][x ^ 1];
11     son[t][x ^ 1] = k;
12     size[t] = size[k];
13     size[k] = size[son[k][0]] + size[son[k][1]] + g[k];
14     k = t;
15 }
turn

相关文章:

  • 2021-11-13
  • 2021-11-17
  • 2021-09-13
  • 2022-12-23
  • 2022-12-23
  • 2021-12-15
  • 2021-09-23
  • 2022-12-23
猜你喜欢
  • 2021-10-31
  • 2021-08-28
  • 2021-11-02
  • 2021-05-27
  • 2021-08-04
  • 2022-02-10
相关资源
相似解决方案