平衡树Treap
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int INF=0x3fffffff;
int node_cnt; //结点计数器
struct Node;
typedef Node * pNode; //结点指针
struct Node //结点定义
{
int key, val, size, same;
pNode ls, rs;
Node(int val):val(val), size(1), same(1){ ls=rs=NULL; key=rand(); }
int lsize(){ return ls?ls->size:0; } //避免空指针查询
int rsize(){ return rs?rs->size:0; } //避免空指针查询
void update(){ size=lsize()+rsize()+same; }
};
void zig(pNode &p) //左旋
{
pNode tmp=p->rs; p->rs=tmp->ls; tmp->ls=p; tmp->size=p->size; p->update(); p=tmp;
}
void zag(pNode &p) //右旋
{
pNode tmp=p->ls; p->ls=tmp->rs; tmp->rs=p; tmp->size=p->size; p->update(); p=tmp;
}
void treap_insert(int x, pNode &p) //插入结点
{
if(!p){ p=new Node(x); node_cnt++; return; };
if(p->val==x) { p->same++; p->update(); node_cnt++; return; }
if(x< p->val) { treap_insert(x, p->ls); if(p->key>p->ls->key) zag(p); }
if(x> p->val) { treap_insert(x, p->rs); if(p->key>p->rs->key) zig(p); }
p->update();
}
void treap_delete(int x, pNode &p) //删除结点
{
if(!p) return; //没找到
if(x<p->val) treap_delete(x, p->ls);
if(x>p->val) treap_delete(x, p->rs);
if(x==p->val)
{
if(p->same>1) { p->same--; p->update(); node_cnt--; return; } //多个相同的,删除一个
if(!(p->ls) && !(p->rs)){ delete p; p=NULL; node_cnt--; return; } //没有子树,直接删除
else if(!p->ls && p->rs){ delete p; p=p->rs; node_cnt--; } //只有右子树
else if(p->ls && !p->rs){ delete p; p=p->ls; node_cnt--; } //只有左子树
else //有左、右子树
{
if(p->ls->key<p->rs->key) zag(p), treap_delete(x, p->rs);
else zig(p), treap_delete(x, p->ls);
}
}
p->update();
}
int treap_rank(int x, const pNode &p) //查询元素排名
{
if(!p) return 0; //没找到
if(p->val==x) return p->lsize()+1;
else if(p->val <x) return p->lsize()+p->same+treap_rank(x, p->rs);
else return treap_rank(x, p->ls); //这个函数是存在问题的,如果要查找的数字不存在,排名就是N或0,该如何解决?
}
int treap_find(int k, const pNode &p) //查询排名为k的元素
{
if(k>node_cnt) return INF; //如果k大于实际节点数,返回无穷大
int tmp=p->lsize()+p->same;
if(p->lsize()<k && k<=tmp) return p->val;
else if(k>tmp) return treap_find(k-tmp, p->rs);
else return treap_find(k, p->ls);
}
int treap_pre(int x, const pNode &p) //查找x的前驱
{
if(!p) return -INF; //找不到返回无穷小
if(x<=p->val) return treap_pre(x, p->ls);
else return max(p->val, treap_pre(x, p->rs));
}
int treap_next(int x, const pNode &p) //查找x的后继
{
if(!p) return INF; //找不到返回无穷大
if(x>=p->val) return treap_next(x, p->rs);
else return min(p->val, treap_next(x, p->ls));
}
int main()
{
int n;
pNode root=NULL;
scanf("%d", &n);
for(int i=1, opt, x; i<=n; i++)
{
scanf("%d%d", &opt, &x);
if(opt==1) treap_insert(x, root);
if(opt==2) treap_delete(x, root);
if(opt==3) printf("%d\n", treap_rank(x, root));
if(opt==4) printf("%d\n", treap_find(x, root));
if(opt==5) printf("%d\n", treap_pre(x, root) );
if(opt==6) printf("%d\n", treap_next(x, root));
}
return 0;
}
平衡树Treap的更多相关文章
- hiho #1325 : 平衡树·Treap
#1325 : 平衡树·Treap 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho:小Hi,我发现我们以前讲过的两个数据结构特别相似. 小Hi:你说的是哪两个啊? ...
- hiho一下103周 平衡树·Treap
平衡树·Treap 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho:小Hi,我发现我们以前讲过的两个数据结构特别相似. 小Hi:你说的是哪两个啊? 小Ho:就是二 ...
- 算法模板——平衡树Treap 2
实现功能:同平衡树Treap 1(BZOJ3224 / tyvj1728) 这次的模板有了不少的改进,显然更加美观了,几乎每个部分都有了不少简化,尤其是删除部分,这个参照了hzwer神犇的写法,在此鸣 ...
- 【山东省选2008】郁闷的小J 平衡树Treap
小J是国家图书馆的一位图书管理员,他的工作是管理一个巨大的书架.虽然他很能吃苦耐劳,但是由于这个书架十分巨大,所以他的工作效率总是很低,以致他面临着被解雇的危险,这也正是他所郁闷的.具体说来,书架由N ...
- Hihocoder 1325 平衡树·Treap(平衡树,Treap)
Hihocoder 1325 平衡树·Treap(平衡树,Treap) Description 小Ho:小Hi,我发现我们以前讲过的两个数据结构特别相似. 小Hi:你说的是哪两个啊? 小Ho:就是二叉 ...
- HihoCoder 1325 平衡树·Treap
HihoCoder 1325 平衡树·Treap 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho:小Hi,我发现我们以前讲过的两个数据结构特别相似. 小Hi:你说 ...
- 普通平衡树Treap(含旋转)学习笔记
浅谈普通平衡树Treap 平衡树,Treap=Tree+heap这是一个很形象的东西 我们要维护一棵树,它满足堆的性质和二叉查找树的性质(BST),这样的二叉树我们叫做平衡树 并且平衡树它的结构是接近 ...
- HihoCoder1325 : 平衡树·Treap(附STL版本)
平衡树·Treap 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho:小Hi,我发现我们以前讲过的两个数据结构特别相似. 小Hi:你说的是哪两个啊? 小Ho:就是二 ...
- luoguP3369[模板]普通平衡树(Treap/SBT) 题解
链接一下题目:luoguP3369[模板]普通平衡树(Treap/SBT) 平衡树解析 #include<iostream> #include<cstdlib> #includ ...
- 2021.12.06 平衡树——Treap
2021.12.06 平衡树--Treap https://www.luogu.com.cn/blog/HOJQVFNA/qian-xi-treap-ping-heng-shu 1.二叉搜索树 1.1 ...
随机推荐
- Simulink 产品说明
Simulink 产品说明 仿真和基于模型的设计 Simulink® 是一个模块图环境,用于多域仿真以及基于模型的设计.它支持系统级设计.仿真.自动代码生成以及嵌入式系统的连续测试和验证.Simuli ...
- java集合介绍(List,Set,Map)
前言 介绍java的常用集合+各个集合使用用例 欢迎转载,请注明作者和出处哦☺ 参考: 1,<Java核心编程技术(第二版)> 2, http://www.cnblogs.com/Litt ...
- C# 获取当前服务器运行程序的根目录,获取当前运行程序物理路径
C# 获取当前服务器运行程序的根目录,获取当前运行程序物理路径 string tmpRootDir = AppDomain.CurrentDomain.BaseDirectory;//获得当前服务器程 ...
- cocos web 多端口运行
cocos2d-js 也是比较普遍的游戏开发工具之一吧,今天想同时启动多个js项目来看下效果,结果百度不到添加端口的方法,又得去翻源码.... cocos run -p web 只要运行在本地就可以启 ...
- 【spring源码分析】IOC容器初始化(四)
前言:在[spring源码分析]IOC容器初始化(三)中已经分析了BeanDefinition注册之前的一些准备工作,下面将进入BeanDefinition注册的核心流程. //DefaultBean ...
- dedecms织梦的不同栏目调用不同banner图的方法
在做织梦站的时候我们会有不同的栏目,比如联系我们,产品中心等等,banner也不一样,方法如下: 我们可以使用织梦的顶级栏目ID标签,把图片命名成顶级栏目typeid ,代码如下: <img s ...
- 【git】git hello world
以前不怎么会用. http://blog.sina.com.cn/s/blog_1485511700102xdig.html git add 文件夹/ 添加整个文件夹及内容 gi ...
- 软工+C(4): Alpha/Beta换人
// 上一篇:超链接 // 下一篇:工具和结构化 注:在一次软件工程讨论课程进度设计的过程中,出现了这个关于 Alpha/Beta换人机制的讨论,这个机制在不同学校有不同的实施,本篇积累各方观点,持续 ...
- 关于 Be 主
大三在校生 每天不定刷 Leetcode POJ HDU 以及其他算法专题 自己很菜 还没有能力可以帮助别的旁友解决问题 :-( 毕竟有个人每天看着你写代码还是很幸福的事情呢 还是要骄傲夸一下 FH ...
- To B Vs To C
谈谈 To B 业务的难点https://tangjie.me/blog/259.html