这次我们来讲一讲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. Material04 MdCardModule和MdButtonModule综合运用

    设计需求:设计一个登陆页面 1 模块导入 1.1 将MdCardModule和MdButtonModule模块导入到共享模块中 import { NgModule } from '@angular/c ...

  2. keystone V3 与Microsoft Active Directory(AD)的集成

    一  环境准备 1. 安装或在现有的windows server2008,操作Microsoft Acitve Directory(下面简称AD).欲了解AD请看系列文章[深入浅出ActiveDire ...

  3. macox下编译snappy静态库

    源代码地址:https://github.com/google/snappy 下载 git clone https://github.com/google/snappy 编译 进入snappy源代码文 ...

  4. git for c#,子文件的加入

    private static void SubDirFile() { string wkDir = @"E:\DotNet2010\单位project\Git.Client\lib2Test ...

  5. 快速上手virtualenv

    五分钟轻松学会管理项目开发环境. 在开发Python应用程序的时候,系统安装的Python3只有一个版本:3.x.所有第三方的包都会被pip安装到Python3的site-packages目录下. p ...

  6. 理解vuex的状态管理模式架构

    理解vuex的状态管理模式架构 一: 什么是vuex?官方解释如下:vuex是一个专为vue.js应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证以一种可预测的 ...

  7. 【quickhybrid】H5和原生的职责划分

    前言 在JSBridge实现后,前端网页与原生的交互已经通了,接下来就要开始规划API,明确需要提供哪一些功能来供前端调用. 但是在这之前,还有一点重要工作需要做: 明确H5与Native的职责划分, ...

  8. 【转】JAVA处理线程超时

    在实际业务中,由其是多线程并开业务中,经常会遇到某个线程执行超时.而程序如果不捕获这类情况,就会导致程序一直处于等待状态,从而影响后续线程的运行.比如说网络通迅.单任务下的复杂数据库查询等,通常处理这 ...

  9. Spring:Bean生命周期

    关于Bean生命周期,我在网上找了两张图: 图1: 图2: 总结起来就是: Bean构建: Bean对象创建 > @Autowired | @Resource> @PostConstruc ...

  10. springboot+shiro

    作者:纯洁的微笑 出处:http://www.ityouknow.com/ 这篇文章我们来学习如何使用Spring Boot集成Apache Shiro.安全应该是互联网公司的一道生命线,几乎任何的公 ...