【模板】Treap
Treap,又称树堆,是一种通过堆性质来维持BST平衡的数据结构。具体体现在对于树上每一个点来说,既有BST维护的值,又有一个堆维护的随机生成的值。维护平衡性的办法是根据堆维护的值的相对大小关系进行左旋和右旋这两种操作,在旋转的前后,依然满足BST性质。
latest updated:2019.2.25
代码如下
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
const int inf=0x3f3f3f3f;
struct node{
#define ls(p) t[p].lc
#define rs(p) t[p].rc
int lc,rc,val,rd,cnt,size;
}t[maxn];
int tot,root;
inline int newnode(int val){
++tot,t[tot].val=val,t[tot].rd=rand(),t[tot].size=t[tot].cnt=1;
return tot;
}
inline void pushup(int p){
t[p].size=t[ls(p)].size+t[rs(p)].size+t[p].cnt;
}
inline void zig(int &p){
int lson=ls(p);
ls(p)=rs(lson),rs(lson)=p,p=lson;
pushup(rs(p)),pushup(p);
}
inline void zag(int &p){
int rson=rs(p);
rs(p)=ls(rson),ls(rson)=p,p=rson;
pushup(ls(p)),pushup(p);
}
void insert(int &p,int val){
if(!p)p=newnode(val);
else if(val==t[p].val)++t[p].size,++t[p].cnt;
else if(val<t[p].val){
++t[p].size,insert(ls(p),val);
if(t[ls(p)].rd>t[p].rd)zig(p);
}else{
++t[p].size,insert(rs(p),val);
if(t[rs(p)].rd>t[p].rd)zag(p);
}
}
void remove(int &p,int val){
if(!p)return;
else if(val<t[p].val)--t[p].size,remove(ls(p),val);
else if(val>t[p].val)--t[p].size,remove(rs(p),val);
else{
if(t[p].cnt>1)--t[p].cnt,--t[p].size;
else if(!ls(p)||!rs(p))p=ls(p)+rs(p);
else if(t[ls(p)].rd>t[rs(p)].rd)zig(p),remove(p,val);
else zag(p),remove(p,val);
}
}
int kth(int p,int k){
if(k<=t[ls(p)].size)return kth(ls(p),k);
else if(k>t[ls(p)].size+t[p].cnt)return kth(rs(p),k-t[ls(p)].size-t[p].cnt);
else return t[p].val;
}
int getrank(int p,int val){
if(t[p].val==val)return t[ls(p)].size+1;
else if(val<t[p].val)return getrank(ls(p),val);
else return getrank(rs(p),val)+t[p].cnt+t[ls(p)].size;
}
int getpre(int p,int val){
if(!p)return -inf;
else if(t[p].val>=val)return getpre(ls(p),val);
else return max(getpre(rs(p),val),t[p].val);
}
int getnxt(int p,int val){
if(!p)return inf;
else if(t[p].val<=val)return getnxt(rs(p),val);
else return min(getnxt(ls(p),val),t[p].val);
}
int main(){
int n;scanf("%d",&n);
while(n--){
int opt,val;
scanf("%d%d",&opt,&val);
switch(opt){
case 1:insert(root,val);break;
case 2:remove(root,val);break;
case 3:printf("%d\n",getrank(root,val));break;
case 4:printf("%d\n",kth(root,val));break;
case 5:printf("%d\n",getpre(root,val));break;
case 6:printf("%d\n",getnxt(root,val));break;
}
}
return 0;
}
【模板】Treap的更多相关文章
- 模板——Treap
不得不说平衡树博大精深,除了Treap,还有splay,非旋Treap和可持久化数据结构,今天先讲讲Treap,也很感谢这位大佬的博客给予我帮助:http://www.360doc.com/conte ...
- [模板] Treap
插入x 删除x 查询排名为x的数 查询x的排名 求x的前驱.后继 //Stay foolish,stay hungry,stay young,stay simple #include<iostr ...
- 模板—treap
#include<iostream> #include<cstdio> #include<cstdlib> #define INF 0x7fffffff using ...
- 模板——Treap实现名次树
Treap 是一种通过赋予结点随机权值的一种满足堆性质的二叉搜索树,它很好的解决了二叉搜索树顺序插入组成链式的局限性. 名次树是指在treap的每个结点中添加附加域size,表示以它为根的子树的总结点 ...
- LG3369 普通平衡树
题意 维护一些数,其中需要提供以下操作: 1.插入\(x\) 2.删除\(x\)(若有多个相同的数,只删除一个) 3.查询\(x\)的排名(排名定义为比当前数小的数的个数\(+1\)) 4.查询排名为 ...
- treap树模板
///treap树模板 typedef struct Node ///节点的结构体 { Node *l,*r; int val,pri; ///节点的值和优先级 int sz; ///节点子树的节点数 ...
- BZOJ 3224 TYVJ 1728 普通平衡树 [Treap树模板]
3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 7390 Solved: 3122 [Submit][S ...
- 三大平衡树(Treap + Splay + SBT)总结+模板[转]
Treap树 核心是 利用随机数的二叉排序树的各种操作复杂度平均为O(lgn) Treap模板: #include <cstdio> #include <cstring> #i ...
- treap完全版模板
这是我综合poj1442 3481 2352的treap操作 得到treap完全版模板.(经测AC) 结构体Tree { int key; //键值 int size; //该子树总节点个数 int ...
- Treap 模板 poj1442&hdu4557
原理可以看hihocoder上面的讲解,很清楚,不多说了. 模板抄lrj训练指南上面的. /** Treap 实现 名次树 功能: 1.找到排名为k的元素 2.值为x的元素的名次 初始化:Node* ...
随机推荐
- SQL行转列汇总 (转)
PIVOT 用于将列值旋转为列名(即行转列),在 SQL Server 2000可以用聚合函数配合CASE语句实现 PIVOT 的一般语法是:PIVOT(聚合函数(列) FOR 列 in (…) )A ...
- Scrum与看板区别
看板:在制品(work-in-progress, WIP)必须被限制 WIP上限和拉动式生产 1. Scrum与看板简述 Scrum:组织拆分,工作拆分,开发时间拆分,优化发布计划,过程优化 看板 ...
- 注解Annotation
@java.lang.annotation.Target(value={java.lang.annotation.ElementType.TYPE}) @java.lang.annotation.Re ...
- Neo4j学习案例【转】
转自 打怪的蚂蚁 CSDN: https://blog.csdn.net/xgjianstart/article/details/77285334 neo4j有社区版本和企业版.社区版本是免费的,只支 ...
- PAT L3-021 神坛
https://pintia.cn/problem-sets/994805046380707840/problems/994805046577840128 在古老的迈瑞城,巍然屹立着 n 块神石.长老 ...
- [转帖]新的Linux后门开始肆虐 主要攻击中国服务器
新的Linux后门开始肆虐 主要攻击中国服务器 https://www.cnbeta.com/articles/tech/815639.htm 一种新的 Linux 系统后门已经开始肆虐,并主要运行在 ...
- iphone 与 PC端电脑投屏设置
1. iphone端安装: 屏幕投影助手 下载地址 https://itunes.apple.com/cn/app/ping-mu-tou-ying-zhu-shou/id1152332174?mt= ...
- width() 、 height() 方法;innerWidth() 、innerHeight() 方法;outerWidth() 、 outerHeight() 方法的区别
1.width() . height() 方法 设置或返回元素的宽度.高度(不包括内边距.边框或外边距): 2.innerWidth() .innerHeight() 方法 返回元素的宽度.高度(包括 ...
- flask+mako+peewee(下)(解决了Error 2006: MySQL server has gone away)
这篇主要介绍在这次项目中使用的peewee 文档地址:http://peewee.readthedocs.org/en/latest/index.html 首先我们要初始化一个数据库连接对象.这里我使 ...
- 下载系统已经安装的rpm包
下载系统已经安装的rpm包 yum -y install yum-utils 安装yum下载工具 yumdownloader mysql 用yum下载到当前目录 实例:查询mysql安装包[root@ ...