平衡树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 ...
随机推荐
- Jenkins 配置 Git 错误解决:CAfile: C:/Program Files/Git/mingw64/ssl/certs/ca-bundle.crt
错误信息: Failed to connect to repository : Command "C:/tools/Git/bin/git.exe ls-remote -h https:/X ...
- MATLAB中“fitgmdist”的用法及其GMM聚类算法
MATLAB中“fitgmdist”的用法及其GMM聚类算法 作者:凯鲁嘎吉 - 博客园http://www.cnblogs.com/kailugaji/ 高斯混合模型的基本原理:聚类——GMM,MA ...
- java 浅复制 代码
1 类实现Cloneable接口 2 重写clone()方法 3 类变量引用类型无法复制 class Dog extends Pet implements Cloneable{ int c; i ...
- 无法创建保存文件 "afiedt.buf"
我习惯在搜索框输入sqlplus,输入相应的sql语句.但是直接输入ed的时候会报这个错误. 在cmd中登录进去,然后一步一步走,登录进去就可以了. 找到了这两个窗口的一个区别.
- 【spring源码分析】IOC容器初始化(八)
前言:在上文bean加载过程中还要一个非常重要的方法没有分析createBean,该方法非常重要,因此特意提出来单独分析. createBean方法定义在AbstractBeanFactory中: 该 ...
- Linux新手随手笔记1.6
RAID磁盘冗余阵列 1.I/O 速度 2.数据安全性 RAID 0 负载均衡.速度乘以二,但是数据安全性不行,任何一块盘损坏数据都会丢失. RAID 1 安全性性提升2倍,任何一个损坏另一个都有 ...
- jenkins自动化部署vue
一.nodejs配置 首先加入nodejs插件 在配置里面配置这个插件 这样我们就能在自动构建发布的配置里看到nodejs的编译选项了 二.发布配置 首先新建一个自由风格的项目 然后配置构建保留天数和 ...
- Effective C++ 第0章 explicit构造函数
按照默认规定,只有一个参数的构造函数也定义了一个隐式转换,将该构造函数对应数据类型的数据转换为该类对象,如下面所示: class String { String ( const char* p ); ...
- CentOS7.x安装kickstart
kickstart简介 kickstartkickstart是RedHat公司开源的软件,所以对CentOS兼容性最好,是一种无人值守的安装方式就是将手动安装配置的步骤,记录到文件中,然后通过kick ...
- 复习交换代数——Noether正规化
目录 简介 初等启发 证明过程 几何意义 定理应用 参考资料 简介 在交换代数中有如下定理 Noether正规化引理 令$R$是一个有限生成$k$-代数整环,则存在$t_1,\ldots,t_n\in ...