最近开始学习平衡树,在学长的强烈推荐下学习了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】普通平衡树的更多相关文章

  1. 初学 Size Balanced Tree(bzoj3224 tyvj1728 普通平衡树)

    SBT(Size Balance Tree), 即一种通过子树大小(size)保持平衡的BST SBT的基本性质是:每个节点的size大小必须大于等于其兄弟的儿子的size大小: 当我们插入或者删除一 ...

  2. [Bzoj3224][Tyvj1728] 普通平衡树(splay/无旋Treap)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3224 平衡树入门题,学习学习. splay(学习yyb巨佬) #include<b ...

  3. [bzoj3224][tyvj1728][普通平衡树] (pb_ds库自带红黑树)

    Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 1. 插入x数 2. 删除x数(若有多个相同的数,因只删除一个) 3. 查询x数的排名(若有多个相 ...

  4. [BZOJ3224/Tyvj1728]普通平衡树

    本篇博客有详细题解,浅谈算法--splay

  5. 【bzoj3224】 Tyvj1728—普通平衡树

    http://www.lydsy.com/JudgeOnline/problem.php?id=3224 (题目链接) 题意 1. 插入x数:2. 删除x数(若有多个相同的数,因只删除一个):3. 查 ...

  6. tyvj1728 普通平衡树

    为了彻底理解树状数组,试着用树状数组做了下普通平衡树 而树状数组只能离线做,或者保证值的大小在数组可承受的范围内也是可以的,因为要求离线是因为必须事前对所有数离散化. 然后我们看刘汝佳蓝书上的图 利用 ...

  7. [bzoj3196][tyvj1728]普通平衡树

    真是太差了,到现在才打出一个平衡树的板子.. 感谢blackjack大佬提供的数组版treap板子!!基本完全照搬,blackjack太神啦! 但目前我只会这几个最基本的操作(说白了STL的(mult ...

  8. 【BZOJ3224】普通平衡树(splay)

    题意: 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数,因输出最小的排 ...

  9. BZOJ3224/LOJ104 普通平衡树 pb_ds库自带红黑树

    您需要写一种数据结构,来维护一些数,其中需要提供以下操作:1. 插入x2. 删除x(若有多个相同的数,因只删除一个)3. 查询x的排名(若有多个相同的数,因输出最小的排名)4. 查询排名为x的数5. ...

  10. BZOJ3224/LOJ104 普通平衡树 treap(树堆)

    您需要写一种数据结构,来维护一些数,其中需要提供以下操作:1. 插入x2. 删除x(若有多个相同的数,因只删除一个)3. 查询x的排名(若有多个相同的数,因输出最小的排名)4. 查询排名为x的数5. ...

随机推荐

  1. 听翁恺老师mooc笔记(8)--字符串2

    字符串的赋值 字符串的输入与输出 对C语言的基础类型,比如int.double等类型,scanf.printf有专门的格式转换,而对字符串,scanf.printf使用%s格式字符进行输入与输出.当使 ...

  2. 网络1712--c语言第一次作业总结

    1.作业亮点 1.1大家均能较为独立自主地完成第一次c语言作业,无明显抄袭现象 1.2 以下几位同学博文写的较为优秀,可作为范例供大家参考 田亚琴--态度端正,及时回复评论并及时完善修改博文 戴洁-- ...

  3. C语言第八次作业

    一.PTA实验作业 题目1:统计一行文本的单词个数 1.本题PTA提交列表 2.设计思路 // 一个非空格和一个空格代表一个单词 char str[1000]: 存放一行文本 定义 I,j=0:用作循 ...

  4. alpha冲刺总结随笔

    前言:前面乱乱糟糟整了一路,到最后终于可以稳定下来了.安安心心做个总结,然后把之后要做的事情都理清楚好了. 新学长似乎是个正经[并不]大腿. 看起来也不用都是一个人或者跟陈华学长两个人对半开了[突然摸 ...

  5. 201621123050 《Java程序设计》第11周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 本次PTA作业题集多线程 1. 源代码阅读:多线程程序BounceThread 1.1 BallR ...

  6. 开始 Python 之旅

    开始 Python 之旅 课程来源 本课程基于 Python for you and me 教程翻译制作,其中参考了 Python tutorial 和 The Python Standard Lib ...

  7. scrapy csvfeed spider

    class CsvspiderSpider(CSVFeedSpider): name = 'csvspider' allowed_domains = ['iqianyue.com'] start_ur ...

  8. 多种在线地图综合对比,Google,必应,arcgis Online...

    不同网络地图的对比 天地图 坐标系:WGS84 地图配色:   POI数量:丰富      有无建筑:有 地图特点:天地图按照国家标准进行配图,道路.水系.植被等图层用对应颜色渲染, POI信息丰富, ...

  9. JAVA_SE基础——46.引用数据类型变量.值交换[独家深入解析]

    需求:定义一个函数交换数组中两个元素的位置. code 1: import java.util.*; class Demo3 { public static void main(String[] ar ...

  10. 不允许用(a+b)/2这种方式求两个数的均值;如下程序在Linux和32位集成开发环境中运行

    #define MAX(a,b) ((a)>(b)?(a):(b)) #include<stdio.h> int main() { int a = 10; int b = 20; i ...