BZOJ3224_普通平衡树_KEY
平衡二叉树(Balanced Binary Tree)具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。平衡二叉树的常用实现方法有红黑树、AVL、替罪羊树、Treap、伸展树等。 最小二叉平衡树的节点的公式如下 F(n)=F(n-1)+F(n-2)+1 这个类似于一个递归的数列,可以参考Fibonacci数列,1是根节点,F(n-1)是左子树的节点数量,F(n-2)是右子树的节点数量。
平衡树是一种在信息竞赛中常用的数据结构,而Treap也是其中之一。说实话花了一天来屮这个Treap。
Treap简单地来说就是二叉搜索树的升级版,只不过在其基础上增加了一个rand值,并利用堆维护rand值,使二叉搜索树的rand值满足堆的性质。
从而保证Treap的高度基本为logN。
Treap的核心就是一个Rotate,它能保证Treap的性质。
插入:像二叉搜索树一样插入,在子节点不满足堆的性质时Rotate。
删除:先找到节点,如果没有儿子,直接删除。有一个儿子,直接将儿子覆盖到当前节点。有两个儿子,Rotate之后递归向下。
其他操作较简单,看code有解释。
code:
#include <cstdio>
#include <cstdlib>
#include <cstring> int read()
{
char c;while(c=getchar(),(c<''||c>'')&&c!='-');
int x=,y=;c=='-'?y=-:x=c-'';
while(c=getchar(),c>=''&&c<='')x=x*+c-'';
return x*y;
} int N,dist; struct Treap{
int tr[][],cnt,ks[],v[],tot[];
int f[],root;
Treap(){
memset(tr,,sizeof tr);
memset(ks,,sizeof ks);
memset(v,,sizeof v);
cnt=;
} void rotate(int &x,int o)//旋转
{
int k=tr[x][o];
tr[x][o]=tr[k][o^];
tr[k][o^]=x;
f[k]=f[x];//更新
f[x]=f[tr[x][]]+f[tr[x][]]+tot[x];
x=k;
} void Insert(int &x,int val)//插入节点
{
if(!x){
x=++cnt;
ks[x]=rand();
v[x]=val;
tot[x]=;//当前节点共有几个相同的值
f[x]=;
return ;
}f[x]++;//统计当前这个节点的子树共有几个节点
if(val==v[x]){tot[x]++;return ;}
int to=val>v[x];
Insert(tr[x][to],val);
if(ks[tr[x][to]]>ks[x])rotate(x,to);//不满足堆的性质,Rotate
return ;
} void Delete(int &x,int val)//删除
{
if(!x)return ;
if(val==v[x]){
if(tot[x]>){tot[x]--;f[x]--;return ;}
if(!tr[x][]&&!tr[x][]){v[x]=tot[x]=ks[x]=;x=;return ;}
if(!(tr[x][]*tr[x][])){
x=tr[x][]+tr[x][];
return ;
}
rotate(x,);
Delete(x,val);//递归向下
return ;
}
int to=val>v[x];
f[x]--;//减去总结点数
Delete(tr[x][to],val);
f[x]=f[tr[x][0]]+f[tr[x][1]]+tot[x];
return ;
} int QueryX(int x,int val)
{
if(!x)return ;
if(v[x]==val)return f[tr[x][]]+;//小细节,可以直接return左子树总结点+1
int to=val>v[x];
return QueryX(tr[x][to],val)+(to?(f[tr[x][]]+tot[x]):);//如果是访问右子树retun之后要加上f[tr[x][0]]+tot[x]
//查询X的排名
} int QueryK(int x,int kth)
{
if(!x)return ;
if(kth<=f[tr[x][]])return QueryK(tr[x][],kth);//在左子树
if(kth>f[tr[x][]]+tot[x])return QueryK(tr[x][],kth-(f[tr[x][]]+tot[x]));//在右子树
return v[x];//查询排名为X的数
} int pre(int x,int val)//前驱
{
if(!x)return ;
if(v[x]>=val)pre(tr[x][],val);
else{
dist=x;
pre(tr[x][],val);
}
} int bac(int x,int val)//后继
{
if(!x)return ;
if(v[x]<=val)bac(tr[x][],val);
else{
dist=x;
bac(tr[x][],val);
}
}
}T; int main()
{
int W=('Y'+'u'+'a'+'o')*('S'+'h'+'i')*('D'+'o'+'g');
srand(W);
N=read();
while(N--){
int o=read(),x=read();
switch(o){
case :T.Insert(T.root,x);break;
case :T.Delete(T.root,x);break;
case :printf("%d\n",T.QueryX(T.root,x));break;
case :printf("%d\n",T.QueryK(T.root,x));break;
case :dist=,T.pre(T.root,x),printf("%d\n",T.v[dist]);break;
case :dist=,T.bac(T.root,x),printf("%d\n",T.v[dist]);break;
}
}
}
BZOJ3224_普通平衡树_KEY的更多相关文章
- 【BZOJ】3224: Tyvj 1728 普通平衡树(某不科学的oj)
http://www.lydsy.com/JudgeOnline/problem.php?id=3224 无力吐槽,无力吐槽,无力吐槽....... bzoj竟然不能用time(0)我竟然不造!!re ...
- 三大平衡树(Treap + Splay + SBT)总结+模板[转]
Treap树 核心是 利用随机数的二叉排序树的各种操作复杂度平均为O(lgn) Treap模板: #include <cstdio> #include <cstring> #i ...
- 可持久化Trie & 可持久化平衡树 专题练习
[xsy1629]可持久化序列 - 可持久化平衡树 http://www.cnblogs.com/Sdchr/p/6258827.html [bzoj4260]REBXOR - Trie 事实上只是一 ...
- 平衡树初阶——AVL平衡二叉查找树+三大平衡树(Treap + Splay + SBT)模板【超详解】
平衡树初阶——AVL平衡二叉查找树 一.什么是二叉树 1. 什么是树. 计算机科学里面的树本质是一个树状图.树首先是一个有向无环图,由根节点指向子结点.但是不严格的说,我们也研究无向树.所谓无向树就是 ...
- 三大平衡树(Treap + Splay + SBT)总结+模板[转]
Treap树 核心是 利用随机数的二叉排序树的各种操作复杂度平均为O(lgn) Treap模板: #include <cstdio> #include <cstring> #i ...
- 三大平衡树(Treap + Splay + SBT)总结+模板
Treap树 核心是 利用随机数的二叉排序树的各种操作复杂度平均为O(lgn) Treap模板: #include <cstdio> #include <cstring> #i ...
- BZOJ 1901: Zju2112 Dynamic Rankings 区间k大 带修改 在线 线段树套平衡树
之前写线段树套splay数组版..写了6.2k..然后弃疗了.现在发现还是很水的..嘎嘎.. zju过不了,超时. upd:才发现zju是多组数据..TLE一版才发现.然后改了,MLE...手写内存池 ...
- [数据结构-平衡树]普通 FHQ_Treap从入门到精通(注释比代码多系列)
普通 FHQ_Treap从入门到精通(注释比代码多系列) 前提说明,作者写注释太累了,文章里的部分讲解来源于Oi-wiki,并根据代码,有部分增改.本文仅仅发布于博客园,其他地方出现本文,均是未经许可 ...
- [BZOJ3223]Tyvj 1729 文艺平衡树
[BZOJ3223]Tyvj 1729 文艺平衡树 试题描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区 ...
随机推荐
- 如何理解 Learning to rank
转:http://hi.baidu.com/christole/item/23215e364d8418f896f88deb What is Rank? rank就是排序.IR中需要排序的问题很多,最常 ...
- 全链路实践Spring Cloud 微服务架构
Spring Cloud 微服务架构全链路实践Spring Cloud 微服务架构全链路实践 阅读目录: 网关请求流程 Eureka 服务治理 Config 配置中心 Hystrix 监控 服务调用链 ...
- [零基础学JAVA]Java SE基础部分-04. 分支、循环语句
转自:http://redking.blog.51cto.com/27212/116751 1.课程名称:分支.循环 本季为JAVA程序中最重要的部分,在讲解的时候除了讲解各种主要的控制语句(分支语句 ...
- 理解Underscore中的uniq函数
uniq函数,是Underscore中的一个数组去重函数,给它传递一个数组,它将会返回该数组的去重副本. 1 ES6版本去重 在ES6版本中,引入了一个新的数据结构——set,这是一种类似数组的数据结 ...
- CAShapeLayer使用
UIView *showView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)]; [self.view addSubv ...
- 关于浏览器被http://www.51jetso.com/劫持
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/wwkaven/article/details/36373447 近期,新装了一下系统.安装软 ...
- VS2013安装部署过程详解
注意:缺少安装部署的小伙伴,看上一篇有详细介绍 程序在“Release”平台下编译运行没有错误 第一步:“新建”------“项目”------“其他项目类型”------“安装部署”------“I ...
- c#用链表来存储并读取写好的配置文件
别用arraylist,效果没有list好(因为要装箱拆箱,所以会影响性能) 使用list,那我们就来先声明一个List 1) 声明 List<元素类型> myList = new Lis ...
- IDEA+MAVEN构建一个webapp骨架项目(解决一直卡在downloading plugins for问题)
下载:链接:https://pan.baidu.com/s/1jJx73H8 密码:nud0 第一步 我在上面链接下载了这个骨架xml,放进本地(你的目录默认.m2)\repository\org ...
- StringJoiner
示例一 public class StringJoinerTest1 { public static void main(String[] args) { StringJoiner joiner = ...