平衡树Treap模板与原理
这次我们来讲一讲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模板与原理的更多相关文章
- [luogu3369]普通平衡树(treap模板)
解题关键:treap模板保存. #include<cstdio> #include<cstring> #include<algorithm> #include< ...
- 算法模板——平衡树Treap 2
实现功能:同平衡树Treap 1(BZOJ3224 / tyvj1728) 这次的模板有了不少的改进,显然更加美观了,几乎每个部分都有了不少简化,尤其是删除部分,这个参照了hzwer神犇的写法,在此鸣 ...
- luoguP3369[模板]普通平衡树(Treap/SBT) 题解
链接一下题目:luoguP3369[模板]普通平衡树(Treap/SBT) 平衡树解析 #include<iostream> #include<cstdlib> #includ ...
- 洛谷 P3369 【模板】普通平衡树 (Treap)
题目链接:P3369 [模板]普通平衡树 题意 构造一种数据结构满足给出的 6 种操作. 思路 平衡树 平衡树的模板题. 先学习了一下 Treap. Treap 在插入结点时给该结点随机生成一个额外的 ...
- BZOJ 3224 - 普通平衡树 - [Treap][Splay]
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3224 Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中 ...
- 普通平衡树Treap(含旋转)学习笔记
浅谈普通平衡树Treap 平衡树,Treap=Tree+heap这是一个很形象的东西 我们要维护一棵树,它满足堆的性质和二叉查找树的性质(BST),这样的二叉树我们叫做平衡树 并且平衡树它的结构是接近 ...
- 2021.12.06 平衡树——Treap
2021.12.06 平衡树--Treap https://www.luogu.com.cn/blog/HOJQVFNA/qian-xi-treap-ping-heng-shu 1.二叉搜索树 1.1 ...
- hiho #1325 : 平衡树·Treap
#1325 : 平衡树·Treap 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho:小Hi,我发现我们以前讲过的两个数据结构特别相似. 小Hi:你说的是哪两个啊? ...
- 写一个迷你版Smarty模板引擎,对认识模板引擎原理非常好(附代码)
前些时间在看创智博客韩顺平的Smarty模板引擎教程,再结合自己跟李炎恢第二季开发中CMS系统写的tpl模板引擎.今天就写一个迷你版的Smarty引擎,虽然说我并没有深入分析过Smarty的源码,但是 ...
随机推荐
- 怎样将word文件转化为Latex文件:word-to-latex-2.56具体解释
首先推荐大家读一读这篇博文:http://blog.csdn.net/ibingow/article/details/8613556 --------------------------------- ...
- 【LeetCode-面试算法经典-Java实现】【053-Maximum Subarray(最大子数组和)】
[053-Maximum Subarray(最大子数组和)] [LeetCode-面试算法经典-Java实现][全部题目文件夹索引] 原题 Find the contiguous subarray w ...
- Windows环境下部署Tomcat服务器图文教程
Tomcat是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP程序的首选. 本文将详细介绍在Windows环境下 ...
- 【转载】Java系列笔记(1) - Java 类加载与初始化
Java系列笔记(1) - Java 类加载与初始化 原文地址:http://www.cnblogs.com/zhguang/p/3154584.html 目录 类加载器 动态加载 链接 初始化 示例 ...
- Redis的那些最常见面试问题
随笔:经过长达一周的奔波和面试,电话面试,回首今天终于成功的入职了,总共面试了大概10家公司,包括阿里,京东,IBM等等,京东技术过了,学历因为非统招就被pass了,阿里面了2次电话面试就没下文了,估 ...
- 【功能代码】---5 JS通过事件隐藏显示元素
JS通过事件隐藏显示元素 在开发中,很多时候我们需要点击事件,才显示隐藏元素.那如何做到页面刚开始就把标签隐藏. 有两种方法: (1) display:none <div id=" ...
- Android开发——diglog cancel与dismiss方法区别
AlertDialog dismiss 和 cancel方法的区别 AlertDialog使用很方便,但是有一个问题就是:dismiss方法和cancel方法到底有什么不同? 今天有时间,看了看源 ...
- Android系统拍照之后回显并且获取文件路径
/*调用拍照返回*/ case PHOTO_REQUEST_GALLERY: if (data != null) { Uri uri = data.getData(); String photopat ...
- JMeter3.0脚本中文乱码解决方法
修改apache-jmeter-3.0\bin\jmeter.properties文件,编辑jsyntaxtextarea.font.family=宋体.
- 指针变量的*p,p以及&p的区别
23/7/2017 决定夯实基础,回顾指针的知识点,该博文转载于CSDN博主百家晓东,小部分修改,外加编译图引证 正文如下: 以下面的情况说明: int a = 5; int* p = &a ...