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的更多相关文章

  1. 模板——Treap

    不得不说平衡树博大精深,除了Treap,还有splay,非旋Treap和可持久化数据结构,今天先讲讲Treap,也很感谢这位大佬的博客给予我帮助:http://www.360doc.com/conte ...

  2. [模板] Treap

    插入x 删除x 查询排名为x的数 查询x的排名 求x的前驱.后继 //Stay foolish,stay hungry,stay young,stay simple #include<iostr ...

  3. 模板—treap

    #include<iostream> #include<cstdio> #include<cstdlib> #define INF 0x7fffffff using ...

  4. 模板——Treap实现名次树

    Treap 是一种通过赋予结点随机权值的一种满足堆性质的二叉搜索树,它很好的解决了二叉搜索树顺序插入组成链式的局限性. 名次树是指在treap的每个结点中添加附加域size,表示以它为根的子树的总结点 ...

  5. LG3369 普通平衡树

    题意 维护一些数,其中需要提供以下操作: 1.插入\(x\) 2.删除\(x\)(若有多个相同的数,只删除一个) 3.查询\(x\)的排名(排名定义为比当前数小的数的个数\(+1\)) 4.查询排名为 ...

  6. treap树模板

    ///treap树模板 typedef struct Node ///节点的结构体 { Node *l,*r; int val,pri; ///节点的值和优先级 int sz; ///节点子树的节点数 ...

  7. BZOJ 3224 TYVJ 1728 普通平衡树 [Treap树模板]

    3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 7390  Solved: 3122 [Submit][S ...

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

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

  9. treap完全版模板

    这是我综合poj1442 3481 2352的treap操作 得到treap完全版模板.(经测AC) 结构体Tree { int key; //键值 int size; //该子树总节点个数 int ...

  10. Treap 模板 poj1442&hdu4557

    原理可以看hihocoder上面的讲解,很清楚,不多说了. 模板抄lrj训练指南上面的. /** Treap 实现 名次树 功能: 1.找到排名为k的元素 2.值为x的元素的名次 初始化:Node* ...

随机推荐

  1. VS2013安装和单元测试

    1. VC2013安装过程及使用感受 刚上大一的时候老师推荐我们用VC++6.0.当时也就听了老师的话用VC++6.0编程了一段时间.后来上了大二买了电脑VC++6.0支持不了WIN8.1所以我就开始 ...

  2. 12.16 Daily Scrum

      Today's Task Tomorrow's Task 丁辛 实现和菜谱相关的餐厅列表. 实现和菜谱相关的餐厅列表.             邓亚梅             美化搜索框UI. 美 ...

  3. 数学战神app(小学生四则运算app)开发需求及进度

    项目名字:“数学战神” 开发环境:Android eclipse 团队名称:战神联盟 团队成员:陈思明,许家豪,王宏财,吴旭涛 在之前的四则运算APP中添加更多的实用功能,并在各种平台推广宣传. 预加 ...

  4. about use Vue of methods

    methods 处理事件 methods 在vue中处理一些逻辑方面的事情.vue事件监听的方式看上去有点违背分离的传统观念.而实际上vue中所有事件的处理方式和表达式都是严格绑定在当前的视图的vie ...

  5. OSI的七层模型介绍

    应用层: 文件传输,电子邮件,文件服务,虚拟终端 TFTP,HTTP,SNMP,FTP,SMTP,DNS,Telnet 表示层: 数据格式化,代码转换,数据加密 没有协议. (信息的语法语义以及它们的 ...

  6. React componentWillUpdate

    <!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8" ...

  7. python删除数组元素导致跳过元素

    复现的情况大概可以写成这样 abc = [1, 2, 2, 3, 4] print abc for index, i in enumerate(abc): if i == 2: del abc[ind ...

  8. sql server2005查询分析器显示行号方法

    工具栏:工具--选项--文本编辑器---所有语言--右边复选框 行号 打上勾就ok了

  9. 读取excel思路

    1.输入地址 2.输入指定的sheet  通过sheet()[]方式指定 3.输入执行的单元位置 通过 .cell_value(x,y)方式指定 示例 data = xlrd.open_workboo ...

  10. 使用vscode 编写Markdown文件

    markdown简单语法参考下面简单事例: # 一级标题 1. 有序列表1 >1. 有序列表1 >>- *test1* >>- **test2** >>- * ...