【BZOJ3224】【tyvj1728】普通平衡树
最近开始学习平衡树,在学长的强烈推荐下学习了AVL、红黑树、splay(以上我都还没学)treap。
首先讲一下个人对treap(树堆)的理解。
treap,顾名思义,就是tree+heap,首先因为treap是一棵平衡树,因此它满足二叉排序树的性质,接下来,为了防止BST退化成一条链,它使用了随机化的方式给每个点分布一个优先级,然后要求优先级满足堆的性质,但不必是一棵完全二叉树,这样的效率期望就是每次基础操作\( \log n \)的。
然后简单讲一下树堆的基础操作,代码参见例题与AC代码。
1.插入 平衡树最基础的操作之一就是插入一个新节点,首先我们按照BST的性质插入这个节点,接下来按照优先级进行旋转维护堆的性质,这样就可以了。
2.删除 平衡树最基础的操作之二就是删除一个原有节点,同样的我们按照BST的性质找到这个节点,然后按照BST的方法删除它,接下来维护堆的性质即可。
3.查找 平衡树最基础的操作之三就是查找,一般主要包含2种查找:1)给定一个权值,查找排名 2)给定一个排名,查找权值 这2种操作是大同小异的,都只需要按照BST的性质来进行即可。
下面是本题题解。
题目就是平衡树最基础的操作裸题,所以就直接参考上面所说的以及代码就好了。(1912KB 232ms on BZOJ)
- #include <stdio.h>
- #define getchar() (S==TT&&(TT=(S=BB)+fread(BB,1,1<<15,stdin),S==TT)?EOF:*S++)
- char BB[<<],*TT=BB,*S=BB;
- inline int read(){
- int x=,f=;char ch=getchar();
- while (ch<''||ch>'') f=ch=='-'?-:,ch=getchar();
- while (ch>=''&&ch<='') x=(x<<)+(x<<)+ch-'',ch=getchar();
- return x*f;
- }
- inline int rad(){
- static int x=;
- x^=x<<,x^=x>>,x^=x<<;return x;
- }
- struct treap{
- treap *ls,*rs;
- int val,pri,cnt,sz;
- treap(int val):val(val){ls=rs=NULL,cnt=sz=,pri=rad();}
- void combine(){sz=cnt;if (ls!=NULL) sz+=ls->sz;if (rs!=NULL) sz+=rs->sz;}
- }*root;
- inline void lrotate(treap* &x){treap *y=x->rs;x->rs=y->ls;y->ls=x;y->sz=x->sz;x->combine();x=y;}
- inline void rrotate(treap* &x){treap *y=x->ls;x->ls=y->rs;y->rs=x;y->sz=x->sz;x->combine();x=y;}
- inline void Insert(treap* &x,int val){
- if (x==NULL){x=new treap(val); return;}
- if (val==x->val) x->cnt++;
- else if (val>x->val){Insert(x->rs,val);if (x->rs->pri<x->pri) lrotate(x);}
- else {Insert(x->ls,val);if (x->ls->pri<x->pri) rrotate(x);}x->combine();
- }
- void Delete(treap *&x,int val){
- if (x==NULL) return;
- if (val==x->val){
- if (x->cnt>) x->cnt--,x->sz--;
- else if (x->ls==NULL||x->rs==NULL){
- treap *t=x;
- if (x->ls==NULL) x=x->rs;
- else x=x->ls;
- delete t;
- }
- else if (x->ls->pri<x->rs->pri)
- rrotate(x),Delete(x,val);
- else lrotate(x),Delete(x,val);
- }
- else if (val<x->val) x->sz--,Delete(x->ls,val);
- else x->sz--,Delete(x->rs,val);
- }
- inline int find(treap *x,int val){
- if (x==NULL) return ;
- if (x->ls==NULL){
- if (val==x->val) return ;
- if (val>x->val) return find(x->rs,val)+x->cnt;
- return ;
- }
- if (val==x->val)return x->ls->sz+;
- if (val<x->val) return find(x->ls,val);
- return find(x->rs,val)+x->ls->sz+x->cnt;
- }
- inline int find_rank(treap *x,int k){
- if (x==NULL) return ;
- if (x->ls==NULL){
- if (k<=x->cnt) return x->val;
- else return find_rank(x->rs,k-x->cnt);
- }
- if (k<=x->ls->sz) return find_rank(x->ls,k);
- if (k>x->ls->sz+x->cnt) return find_rank(x->rs,k-x->ls->sz-x->cnt);
- return x->val;
- }
- int find_pre(treap *x,int val,int ans){
- if (x==NULL) return ans;
- if (val>x->val) return find_pre(x->rs,val,x->val);
- return find_pre(x->ls,val,ans);
- }
- int find_nxt(treap *x,int val,int ans){
- if (x==NULL) return ans;
- if (val<x->val) return find_nxt(x->ls,val,x->val);
- return find_nxt(x->rs,val,ans);
- }
- int main(){
- int q=read();
- while (q--){
- int opt=read(),x=read();
- switch (opt){
- case :Insert(root,x); break;
- case :Delete(root,x); break;
- case :printf("%d\n",find(root,x)); break;
- case :printf("%d\n",find_rank(root,x)); break;
- case :printf("%d\n",find_pre(root,x,-)); break;
- case :printf("%d\n",find_nxt(root,x,-)); break;
- }
- }
- }
【BZOJ3224】【tyvj1728】普通平衡树的更多相关文章
- 初学 Size Balanced Tree(bzoj3224 tyvj1728 普通平衡树)
SBT(Size Balance Tree), 即一种通过子树大小(size)保持平衡的BST SBT的基本性质是:每个节点的size大小必须大于等于其兄弟的儿子的size大小: 当我们插入或者删除一 ...
- [Bzoj3224][Tyvj1728] 普通平衡树(splay/无旋Treap)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3224 平衡树入门题,学习学习. splay(学习yyb巨佬) #include<b ...
- [bzoj3224][tyvj1728][普通平衡树] (pb_ds库自带红黑树)
Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 1. 插入x数 2. 删除x数(若有多个相同的数,因只删除一个) 3. 查询x数的排名(若有多个相 ...
- [BZOJ3224/Tyvj1728]普通平衡树
本篇博客有详细题解,浅谈算法--splay
- 【bzoj3224】 Tyvj1728—普通平衡树
http://www.lydsy.com/JudgeOnline/problem.php?id=3224 (题目链接) 题意 1. 插入x数:2. 删除x数(若有多个相同的数,因只删除一个):3. 查 ...
- tyvj1728 普通平衡树
为了彻底理解树状数组,试着用树状数组做了下普通平衡树 而树状数组只能离线做,或者保证值的大小在数组可承受的范围内也是可以的,因为要求离线是因为必须事前对所有数离散化. 然后我们看刘汝佳蓝书上的图 利用 ...
- [bzoj3196][tyvj1728]普通平衡树
真是太差了,到现在才打出一个平衡树的板子.. 感谢blackjack大佬提供的数组版treap板子!!基本完全照搬,blackjack太神啦! 但目前我只会这几个最基本的操作(说白了STL的(mult ...
- 【BZOJ3224】普通平衡树(splay)
题意: 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数,因输出最小的排 ...
- BZOJ3224/LOJ104 普通平衡树 pb_ds库自带红黑树
您需要写一种数据结构,来维护一些数,其中需要提供以下操作:1. 插入x2. 删除x(若有多个相同的数,因只删除一个)3. 查询x的排名(若有多个相同的数,因输出最小的排名)4. 查询排名为x的数5. ...
- BZOJ3224/LOJ104 普通平衡树 treap(树堆)
您需要写一种数据结构,来维护一些数,其中需要提供以下操作:1. 插入x2. 删除x(若有多个相同的数,因只删除一个)3. 查询x的排名(若有多个相同的数,因输出最小的排名)4. 查询排名为x的数5. ...
随机推荐
- Beta第一天
听说
- Beta冲刺 第五天
Beta冲刺 第五天 1. 昨天的困难 1.昨天的困难主要是在类的整理上,一些逻辑理不清,也有一些类写的太绝对了,扩展性就不那么好了,所以,昨天的困难就是在重构上. 页面结构太凌乱,之前没有统筹好具体 ...
- lambda及参数绑定
一.介绍 对于STL中的算法,我们都可以传递任何类别的可调用对象.对于一个对象或一个表达式,如果可以对其使用调用运算符,则称它为可调用的.即,如果e是一个可调用的表达式,则我们可以编写代码e(ar ...
- Scrum 冲刺 总结
Scrum 冲刺 总结 冲刺阶段链接 Scrum冲刺第一天 Scrum冲刺第二天 Scrum冲刺第三天 Scrum冲刺第四天 Scrum冲刺第五天 Scrum冲刺第六天 Scrum冲刺第七天 冲刺阶段 ...
- windows系统下安装 node.js (node.js安装及环境配置)
node.js简介 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境. Node.js 使用了一个事件驱动.非阻塞式 I/O 的模型,使其轻量又高效. Node. ...
- C# 使用 GDI+ 给图片添加文字,并使文字自适应矩形区域
需求 需求是要做一个编辑文字的页面.用户在网页端写文字,文字区域是个矩形框,用户可以通过下方的拖动条调节文字大小. 如下图: 提交数据的时候前端传文字区域的左上角和右下角定位给后台.因为前端的字体大小 ...
- Python-面向对象(二)-Day7
1.字段 12.方法 43.属性 63.1.属性的基本使用 73.2.实例:对于主机列表 83.3.属性的两种定义方式 94.对于类的成员而言都有两种形式: 144.1.私有成员和公有成员的访问限制不 ...
- JAVA中的Log4j
Log4j的简介: 使用异常处理机制==>异常 使用debug调试(必须掌握) System.out.Print(); 001.控制台行数有限制 002.影响性能 ...
- Spring Security 入门(1-2)Spring Security - 从 配置例子例子 开始我们的学习历程
1.Spring Security 的配置文件 我们需要为 Spring Security 专门建立一个 Spring 的配置文件,该文件就专门用来作为 Spring Security 的配置. &l ...
- Python/ MySQL练习题(一)
Python/ MySQL练习题(一) 查询“生物”课程比“物理”课程成绩高的所有学生的学号 SELECT * FROM ( SELECT * FROM course LEFT JOIN score ...