这次我们来讲一讲Treap(splay以后再更)

平衡树是一种排序二叉树(或二叉搜索树),所以排序二叉树可以迅速地判断两个值的大小,当然操作肯定不止那么多(不然我们还学什么)。

而平衡树在排序二叉树的基础上主要是增加了一个优化:就是高度较为平衡,并可以动态平衡。

而今天要讲的treap就是一种动态平衡的方法。

首先说声抱歉,因为没有那么多的时间,所以无法把左旋和右旋两种操作具体的讲,但是可以看刘汝佳的蓝书,讲得还是挺清楚的。

现在开始。

treap用的是一种比较玄学的方法,就是将每一个点还附上一个随机值,然后按照堆的性质,不管大小根堆都是一样的,所以我们每加入一个值,就利用上浮操作进行旋转,保持堆的性质,且不改变排序二叉树的性质。

操作很好理解,就是每次insert时进行判断就行了,若不满足,则上浮。

具体的排序二叉树的操作,我就不再赘述了,如果要学,可以看刘汝佳的蓝书(感觉在跟刘汝佳打广告)。

下面送上代码。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<ctime>
using namespace std;
int n,root,size,ans;
struct P{
int l,r,sz,key,rd,re;//re为重复次数,key为加入权值
}t[];
void update(int k)
{
t[k].sz=t[t[k].l].sz+t[t[k].r].sz+t[k].re;
}
void left(int &k)//右旋
{
int y=t[k].r;
t[k].r=t[y].l;
t[y].l=k;
t[y].sz=t[k].sz;
update(k);
k=y;
}
void right(int &k)//左旋
{
int y=t[k].l;
t[k].l=t[y].r;
t[y].r=k;
t[y].sz=t[k].sz;
update(k);
k=y;
}
void init(int &k,int x)//加入操作
{
if(k==)
{
size++;
k=size;
t[k].sz=;
t[k].re=;
t[k].key=x;
t[k].rd=rand();
return;
}
t[k].sz++;
if(t[k].key==x) t[k].re++;
else{
if(x>t[k].key)
{
init(t[k].r,x);
if(t[t[k].r].rd<t[k].rd) left(k);//这里和下面都是判断是不是满足堆的性质
}
if(x<t[k].key)
{
init(t[k].l,x);
if(t[t[k].l].rd<t[k].rd) right(k);
}
}
}
void del(int &k,int x)
{
if(k==) return;
if(t[k].key==x)
{
if(t[k].re>)
{
t[k].re--;
t[k].sz--;
return;
}
if(t[k].l*t[k].r==) k=t[k].l+t[k].r;//k代表指针的移动,所以移动到了左或右儿子
else
{
if(t[t[k].l].rd<t[t[k].r].rd){
right(k);
del(k,x);
}
else{
left(k);
del(k,x);
}
}
}
else{
if(x>t[k].key)
{
t[k].sz--;
del(t[k].r,x);
}
else{
t[k].sz--;
del(t[k].l,x);
}
}
}
int rank1(int k,int x)//找x的排名
{
if(k==) return ;
if(t[k].key==x) return t[t[k].l].sz+;
if(x>t[k].key) return t[t[k].l].sz+rank1(t[k].r,x)+t[k].re;
if(x<=t[k].key) return rank1(t[k].l,x);
}
int rank2(int k,int x)//找排名为x的数
{
if(k==) return ;
else if(x<=t[t[k].l].sz) return rank2(t[k].l,x);
else if(x>t[t[k].l].sz+t[k].re) return rank2(t[k].r,x-t[t[k].l].sz-t[k].re);
else return t[k].key;
}
void pre(int k,int x)//找前驱
{
if(k==) return;
if(t[k].key<x)
{
ans=k;
pre(t[k].r,x);
}
else pre(t[k].l,x);
}
void nxt(int k,int x)//找后继
{
if(k==) return;
if(t[k].key>x)
{
ans=k;
nxt(t[k].l,x);
}
else nxt(t[k].r,x);
}
int main()
{
srand(time());
scanf("%d",&n);
for(int i=;i<=n;i++)
{
int num,x;
scanf("%d%d",&num,&x);
if(num==) init(root,x);
if(num==) del(root,x);
if(num==) printf("%d\n",rank1(root,x));
if(num==) printf("%d\n",rank2(root,x));
if(num==)
{
pre(root,x);
printf("%d\n",t[ans].key);
}
if(num==)
{
nxt(root,x);
printf("%d\n",t[ans].key);
}
}
return ;
}

模板题:https://www.luogu.org/problemnew/show/P3369

谢谢大家的观看。

如有不妥之处,请大家指出。

平衡树Treap模板与原理的更多相关文章

  1. [luogu3369]普通平衡树(treap模板)

    解题关键:treap模板保存. #include<cstdio> #include<cstring> #include<algorithm> #include< ...

  2. 算法模板——平衡树Treap 2

    实现功能:同平衡树Treap 1(BZOJ3224 / tyvj1728) 这次的模板有了不少的改进,显然更加美观了,几乎每个部分都有了不少简化,尤其是删除部分,这个参照了hzwer神犇的写法,在此鸣 ...

  3. luoguP3369[模板]普通平衡树(Treap/SBT) 题解

    链接一下题目:luoguP3369[模板]普通平衡树(Treap/SBT) 平衡树解析 #include<iostream> #include<cstdlib> #includ ...

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

    题目链接:P3369 [模板]普通平衡树 题意 构造一种数据结构满足给出的 6 种操作. 思路 平衡树 平衡树的模板题. 先学习了一下 Treap. Treap 在插入结点时给该结点随机生成一个额外的 ...

  5. BZOJ 3224 - 普通平衡树 - [Treap][Splay]

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3224 Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中 ...

  6. 普通平衡树Treap(含旋转)学习笔记

    浅谈普通平衡树Treap 平衡树,Treap=Tree+heap这是一个很形象的东西 我们要维护一棵树,它满足堆的性质和二叉查找树的性质(BST),这样的二叉树我们叫做平衡树 并且平衡树它的结构是接近 ...

  7. 2021.12.06 平衡树——Treap

    2021.12.06 平衡树--Treap https://www.luogu.com.cn/blog/HOJQVFNA/qian-xi-treap-ping-heng-shu 1.二叉搜索树 1.1 ...

  8. hiho #1325 : 平衡树·Treap

    #1325 : 平衡树·Treap 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho:小Hi,我发现我们以前讲过的两个数据结构特别相似. 小Hi:你说的是哪两个啊? ...

  9. 写一个迷你版Smarty模板引擎,对认识模板引擎原理非常好(附代码)

    前些时间在看创智博客韩顺平的Smarty模板引擎教程,再结合自己跟李炎恢第二季开发中CMS系统写的tpl模板引擎.今天就写一个迷你版的Smarty引擎,虽然说我并没有深入分析过Smarty的源码,但是 ...

随机推荐

  1. less新手入门(二) Mixin 混合、带参数的Mixin

    四.mixin  混合 "mix - in"属性来自现有的样式!! 你可以在类选择器和id选择器中使用mixin, .a,#b{ color: rebeccapurple; } . ...

  2. shell脚本删除N天前的目录-----附linux和mac上date命令的不同

    背景: 每日构建的东西.按日期放到不同的目录里. 现在天的构建放到2015-06-01里,明天的就放到2015-06-02里,依次类推.时间久了.须要一个脚本删除N天前的目录.(本例中N=7.即删除一 ...

  3. html5视频标签

    <video width="200" height="200" poster="img/shamo.jpg" src="vi ...

  4. 迪杰斯特拉/dijkstra 算法模板(具体凝视)

    #include <iostream> #include <malloc.h> #include <cstring> #include <stack> ...

  5. HPUX 11.31 MC-SG SGeRAC配置

    HPUX 11.31 MC-SG SGeRAC配置 环境: 系统版本号 hp-unix 11.3v2 1503 serviceguard extension版本号 T1907 实施 1. 磁盘空间划分 ...

  6. jmeter的使用---web测试

    jmeter的使用---web测试 url:http://127.0.0.1:1080/WebTours/ 1.通过badboy录制脚本 1.1输入url点击右侧的跳转按钮,随后右侧显示url界面 1 ...

  7. strus2项目中百度编辑器运用的几点细节

    百度编辑器的运用可以参考我之前写的一篇文章,在java项目中加入百度富文本编辑器.这篇文章是以maven+spring mvc项目进行的,总得来说配置比较简单,但是如果是想在strus2项目中配置ue ...

  8. Java并发编程有多难?这几个核心技术你掌握了吗?

    本文主要内容索引 1.Java线程 2.线程模型 3.Java线程池 4.Future(各种Future) 5.Fork/Join框架 6.volatile 7.CAS(原子操作) 8.AQS(并发同 ...

  9. Pycharm配置(二)

    1.主题 这部分教程主要介绍如何创建一个Python工程并使其具有Pycharm的代码风格.你将会看到Pycharm使你的源码变得非常简洁美观,带有合适的缩进.空格等等,因此Pycharm也是一款代码 ...

  10. c#中treeview的使用方法(转 )

    本文主要介绍treeView控件中,添加,修改.删除节点的操作, 首先当窗体加载的时候,我们添加上图中所示的节点. 当点击“Delete the Selected”按钮时,被选中的节点将被删除. 当点 ...