Treap是一棵拥有键值、优先级两种权值的树

struct node{
int size;//以这个结点为根的子树的结点总数量,用于名次树
int rank;//优先级
int key;//键值
node *son[2];//son[0]是左儿子,son[1]是右儿子
bool operator<(const node &a)const{return rank<a.rank;}
int cmp(int x)const{
if(x==key) return -1;
return x<key?0:1;
}
void update(){//更新size
size=1;
if(son[0]!=NULL) size+=son[0]->size;
if(son[1]!=NULL) size+=son[1]->size;
}
};

1.唯一性

2.期望的插入、删除、查找的时间复杂度都是O(log2 n)

  查找

int find(node *o,int k){//返回元素k的名次
if(o==NULL) return -1;
int d=o->cmp(k);
if(d==-1) return o->son[1]==NULL?1:o->son[1]->size+1;
else if(d==1) return find(o->son[d],k);
else{
int tmp=find(o->son[d],k);
if(tmp==-1) return -1;
else return o->son[1]==NULL?tmp+1:tmp+1+o->son[1]->size;
}
}

3.插入

  

(灰色为先前位置)

  旋转代码

void rotate(node* &o,int d){      //d=0,左旋;d=1,右旋
node *k=o->son[d^1]; //d^1与1-d等价,但是更快
o->son[d^1]=k->son[d]; //图中的x
k->son[d]=o;
o=k; //返回新的根
}

4.删除

  调整至叶子结点后直接删除

void remove(node *&o,int x){
int d=o->cmp(x);
if(d==-1){
if(o->son[0]==NULL) o=o->son[1];
else if(o->son[1]==NULL) o=o->son[0];
else{
int d2=(o->son[0]>o->son[1]?1:0);
rotate(o,d2);
remove(o->son[d2],x);
}
}
else remove(o->son[d],x);
}

5.分裂与合并问题

6.Treap与名次树问题

  例题:hdu4585 "Shaolin"

  题解地址:https://www.cnblogs.com/ynzhang2020/p/15071130.html

百宝箱

 1 struct node{
2 int size;//以这个结点为根的子树的结点总数量,用于名次树
3 int rank;//优先级
4 int key;//键值
5 node *son[2];//son[0]是左儿子,son[1]是右儿子
6 bool operator<(const node &a)const{return rank<a.rank;}
7 int cmp(int x)const{
8 if(x==key) return -1;
9 return x<key?0:1;
10 }
11 void update(){//更新size
12 size=1;
13 if(son[0]!=NULL) size+=son[0]->size;
14 if(son[1]!=NULL) size+=son[1]->size;
15 }
16 };
17 void rotate(node *&o,int d){//d=0,左旋;d=1,右旋
18 node *k=o->son[d^1];//d^1与1-d等价,但是更快
19 o->son[d^1]=k->son[d];
20 k->son[d]=o;
21 o->update();
22 k->update();
23 o=k;
24 }
25 void insert(node *&o,int x){//把x插入到树中
26 if(o==NULL){
27 o=new node();
28 o->son[0]=o->son[1]=NULL;
29 o->rank=rand();
30 o->key=x;
31 o->size=1;
32 }
33 else{
34 int d=o->cmp(x);
35 insert(o->son[d],x);
36 o->update();
37 if(o<o->son[d]) rotate(o,d^1);
38 }
39 }
40 int kth(node *o,int k){//返回第k大的数
41 if(o==NULL||k<=0||k>o->size) return -1;
42 int s=o->son[1]==NULL?0:o->son[1]->size;
43 if(k==s+1) return o->key;
44 else if(k<=s) return kth(o->son[1],k);
45 else return kth(o->son[0],k-s-1);
46 }
47 int find(node *o,int k){//返回元素k的名次
48 if(o==NULL) return -1;
49 int d=o->cmp(k);
50 if(d==-1) return o->son[1]==NULL?1:o->son[1]->size+1;
51 else if(d==1) return find(o->son[d],k);
52 else{
53 int tmp=find(o->son[d],k);
54 if(tmp==-1) return -1;
55 else return o->son[1]==NULL?tmp+1:tmp+1+o->son[1]->size;
56 }
57 }

拿来吧你

二叉树系列之Treap树的更多相关文章

  1. 数据结构与算法系列研究五——树、二叉树、三叉树、平衡排序二叉树AVL

    树.二叉树.三叉树.平衡排序二叉树AVL 一.树的定义 树是计算机算法最重要的非线性结构.树中每个数据元素至多有一个直接前驱,但可以有多个直接后继.树是一种以分支关系定义的层次结构.    a.树是n ...

  2. treap树---Double Queue

    HDU   1908 Description The new founded Balkan Investment Group Bank (BIG-Bank) opened a new office i ...

  3. Treap树

    Treap树算是一种简单的优化策略,这名字大家也能猜到,树和堆的合体,其实原理比较简单,在树中维护一个"优先级“,”优先级“ 采用随机数的方法,但是”优先级“必须满足根堆的性质,当然是“大根 ...

  4. 6天通吃树结构—— 第三天 Treap树

    原文:6天通吃树结构-- 第三天 Treap树 我们知道,二叉查找树相对来说比较容易形成最坏的链表情况,所以前辈们想尽了各种优化策略,包括AVL,红黑,以及今天 要讲的Treap树. Treap树算是 ...

  5. Treap树理解

    title: Treap树理解 comments: true date: 2016-10-06 07:57:37 categories: 算法 tags: Treap树 树 Treap树理解 简介 随 ...

  6. 二叉树系列 - 求两节点的最低公共祖先,例 剑指Offer 50

    前言 本篇是对二叉树系列中求最低公共祖先类题目的讨论. 题目 对于给定二叉树,输入两个树节点,求它们的最低公共祖先. 思考:这其实并不单单是一道题目,解题的过程中,要先弄清楚这棵二叉树有没有一些特殊的 ...

  7. POJ-3481 Double Queue,Treap树和set花式水过!

                                                    Double Queue 本打算学二叉树,单纯的二叉树感觉也就那几种遍历了, 无意中看到了这个题,然后就 ...

  8. bzoj2141 树状数组套Treap树

    题目大意是在能够改变两个数的位置的情况下计算逆序对数 这因为是动态记录逆序对 本来单纯逆序对只要用树状数组计算即可,但这里因为更新,所以利用TReap树的删点和增加点来进行更新 大致是把每个树状数组所 ...

  9. treap树模板

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

  10. poj 2761 Feed the dogs (treap树)

    /************************************************************* 题目: Feed the dogs(poj 2761) 链接: http: ...

随机推荐

  1. 浏览器是如何区分http和https协议的

    浏览器的默认解析 我们在浏览器的地址栏中输入一个域名 taobao.com(不要按回车), 然后将地址栏进行复制,粘贴到文本文件后,发现是 http://taobao.com/. 这是浏览器的默认解析 ...

  2. HTML中javascript的<script>标签使用方法详解

    只要一提到把JavaScript放到网页中,就不得不涉及Web的核心语言--HTML.在当初开发JavaScript的时候,Netscape要解决的一个重要问题就是如何做到让JavaScript既能与 ...

  3. 【数据库数据恢复】Oracle数据库数据恢复案例

    数据库故障:Oracle数据库的ASM磁盘组掉线,ASM实例不能挂载.管理员尝试修复数据库但是没有成功. 数据库数据恢复方案:数据库数据恢复工程师通过分析组成ASM磁盘组的磁盘底层数据,将ASM元数据 ...

  4. Vue中使用model属性

    model属性接收两个参数 类型:{ prop?: string, event?: string } prop 也就是调用该组件的父组件中使用v-model指令绑定的属性 event 对应的是修改pr ...

  5. 几十行代码实现简易版koa~

    application.js const http = require("http")// 洋葱模型 function compose(middleware){ return fu ...

  6. k8s入门_label标签、nodeSelector

    什么是label Label以key/value键值对的形式附加到任何对象上,如Pod,Service,Node, RC(ReplicationController)/RS(ReplicaSet)等. ...

  7. Worksheet使用方法

    1  下载印象笔记: iPhone/iPad在App Store搜索"印象笔记"后下载 安卓在应用市场或在印象笔记官网yinxiang.com下载,图标同上 电脑可至印象笔记官网y ...

  8. 看K线学炒股(8.5)

    郑煤机,这只票之前我亏损拿着,昨日理性分析是要打开上涨空间了,毕竟下半年要挖煤,挖煤要煤机,业绩预期就不会差.好了,亏损票,昨日大涨,清了一些,今日大涨八个点清仓.既然分析是打开上涨空间了,那就应该是 ...

  9. webpackHotMiddleware改造成koa支持的中间件

    const stream = require('stream'); const webpackHot = require('webpack-hot-middleware'); const PassTh ...

  10. 权昌TSC244条码打印机如何加载数据实现大批量打印呢?

    我公司的TSC TTP-244条码打印机,只会改个名称打一张,怎么样改数据或者是加载数据实现大量打印的呢?   解答:   TSC TTP-244条码打印机,是一款性能不错的桌面型条码打印机,最大打印 ...