题目传送门

平衡二叉树(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的更多相关文章

  1. 【BZOJ】3224: Tyvj 1728 普通平衡树(某不科学的oj)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3224 无力吐槽,无力吐槽,无力吐槽....... bzoj竟然不能用time(0)我竟然不造!!re ...

  2. 三大平衡树(Treap + Splay + SBT)总结+模板[转]

    Treap树 核心是 利用随机数的二叉排序树的各种操作复杂度平均为O(lgn) Treap模板: #include <cstdio> #include <cstring> #i ...

  3. 可持久化Trie & 可持久化平衡树 专题练习

    [xsy1629]可持久化序列 - 可持久化平衡树 http://www.cnblogs.com/Sdchr/p/6258827.html [bzoj4260]REBXOR - Trie 事实上只是一 ...

  4. 平衡树初阶——AVL平衡二叉查找树+三大平衡树(Treap + Splay + SBT)模板【超详解】

    平衡树初阶——AVL平衡二叉查找树 一.什么是二叉树 1. 什么是树. 计算机科学里面的树本质是一个树状图.树首先是一个有向无环图,由根节点指向子结点.但是不严格的说,我们也研究无向树.所谓无向树就是 ...

  5. 三大平衡树(Treap + Splay + SBT)总结+模板[转]

    Treap树 核心是 利用随机数的二叉排序树的各种操作复杂度平均为O(lgn) Treap模板: #include <cstdio> #include <cstring> #i ...

  6. 三大平衡树(Treap + Splay + SBT)总结+模板

    Treap树 核心是 利用随机数的二叉排序树的各种操作复杂度平均为O(lgn) Treap模板: #include <cstdio> #include <cstring> #i ...

  7. BZOJ 1901: Zju2112 Dynamic Rankings 区间k大 带修改 在线 线段树套平衡树

    之前写线段树套splay数组版..写了6.2k..然后弃疗了.现在发现还是很水的..嘎嘎.. zju过不了,超时. upd:才发现zju是多组数据..TLE一版才发现.然后改了,MLE...手写内存池 ...

  8. [数据结构-平衡树]普通 FHQ_Treap从入门到精通(注释比代码多系列)

    普通 FHQ_Treap从入门到精通(注释比代码多系列) 前提说明,作者写注释太累了,文章里的部分讲解来源于Oi-wiki,并根据代码,有部分增改.本文仅仅发布于博客园,其他地方出现本文,均是未经许可 ...

  9. [BZOJ3223]Tyvj 1729 文艺平衡树

    [BZOJ3223]Tyvj 1729 文艺平衡树 试题描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区 ...

随机推荐

  1. 有时间,可以研究哈redis的源代码

    1 2 3 4 留位,以后自己用!

  2. Shell,Bash,等脚本学习(有区别)

    二元比较操作符,比较变量或者比较数字.注意数字与字符串的区别.   整数比较   -eq        等于,如:if [ "$a" -eq "$b" ] -n ...

  3. 迷宫问题求解——C++

    迷宫问题思路 根据昨天的博客,有如下几种解决方案 克鲁斯卡尔 ,为避免死循环,需要设定优化路径的次数. Prim,为避免死循环,需要设定优化路径的次数,暂定200次. BFS , 实现简单,无死循环. ...

  4. Perl入门(七) Perl脚本的调试

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/sunshoupo211/article/details/32711165 编程中错误不可避免.调试可 ...

  5. Gluon 实现 dropout 丢弃法

    多层感知机中: hi 以 p 的概率被丢弃,以 1-p 的概率被拉伸,除以  1 - p import mxnet as mx import sys import os import time imp ...

  6. Android杀死进程方法

    1. android.os.Process.killProcess(pid) 只能终止本程序的进程,无法终止其它的 具体代码如下: ?12 Process.killProcess(Process.my ...

  7. STC12LE5620AD RAM问题

    1.此款单片机内部有 sram:768B=512B(aux)+256B(Internal) 2.内部RAM解析 2. 3.内部扩展RAM 4.keil中可以选择内存类型 5. 网上摘抄的一段话: 在S ...

  8. Swift_闭包

    Swift_闭包 点击查看源码 闭包优化 //闭包优化 func testClosures() { //函数做参数 排序 let names = ["XuBaoAiChiYu", ...

  9. App 运行后屏幕顶部和底部各留黑边问题 - iOS

    App 启动后屏幕的顶部和底部各产生一条黑边,App 的内容会被压缩在两个黑条内显示,比例失调的情况. 初步判断是启动页资源图片适配问题. 首先,查看工程 project => General ...

  10. Mysql存储引擎myisam与inndb的区别?

    最近在研究Mysql存储引擎这块,说白了就是如何存储数据.如何为存储的数据建立索引和如何更新.查询数据等技术的实现方法,在此做一个大概总结: 其实在工作中用的最多也就是MYISAM和INNODB,IN ...