朴素的treap
所谓Treap,就是一种二叉查找树,而我们知道二叉查找树,相对来说比较容易形成最坏的链表情况,所以我们有一种数据结构来防止二叉查找树出现最坏情况,那就是Treap。
Treap=tree+heap,Treap就是这样一种既是树又是堆的奇怪的东东。我们每次插入节点时,便随机的给每个节点赋给一个值,我们要求原始数据满足二叉查找树的性质,而随机值要满足堆的性质。
比如下面的一棵树:

首先我们知道各个节点的“优先级”是采用随机数的方法,那么就存在一个问题,当我们插入一个节点后,优先级不满足“堆定义"的。那么我们就要旋转这课树。
①: 左左情况旋转

②: 右右情况旋转

好在我们写一个旋转函数就可以同时维护左旋和右旋了:
void play(Treap* &rr,int d){
Treap *k=rr->ro[d^];
rr->ro[d^]=k->ro[d];//ro[0]是左孩子,ro[1]是右孩子
k->ro[d]=rr;
rr->rub();//rub()函数的作用是重新统计该子树的大小
k->rub();//必须先rr再k,因为现在rr是k的孩子
rr=k;
}
那么我们就可以刷水题了:(洛谷-普通平衡树)
#include<bits/stdc++.h>
#define sight(c) ('0'<=c&&c<='9')
#define RR NULL
#define inf 1<<29
#define random rrsbRRsb
using namespace std;
inline int random(){
static int seed=;
return seed=int(seed*48271LL%);
}
struct Treap{
int key,rap,siz;
Treap *ro[];
Treap(int k){
siz=;
key=k;
rap=random();
ro[]=ro[]=RR;
}
inline void rub() {
siz=;
if (ro[]!=RR) siz+=ro[]->siz;
if (ro[]!=RR) siz+=ro[]->siz;
}
inline int cop(int x){
if (x==key) return -;
return x<key?:;
}
};
inline void read(int &x) {
static char c; static int b;
for (b=,c=getchar();!sight(c);c=getchar()) if (c=='-') b=-;
for (x=;sight(c);c=getchar()) x=x*+c-;
x*=b;
}
void play(Treap* &rr,int d){
Treap *k=rr->ro[d^];
rr->ro[d^]=k->ro[d];
k->ro[d]=rr;
rr->rub();
k->rub();
rr=k;
}
void Insert(Treap* &rr,int x){
if (rr==RR) rr=new Treap(x);
else {
int d=x < rr->key?:;
Insert(rr->ro[d],x);
if (rr->ro[d]->rap > rr->rap)
play(rr,d^);
}
rr->rub();
}
bool Find(Treap *p,int x){
while(p!=RR) {
int d=p->cop(x);
if (d==-) return true;
p=p->ro[d];
}
return false;
}
void Delete(Treap* &t,int x){
int d=t->cop(x);
if (d==-) {
Treap *tmp=t;
if (t->ro[]==RR) {
t=t->ro[];
delete tmp;
tmp=RR;
} else if (t->ro[]==RR) {
t=t->ro[];
delete tmp;
tmp=RR;
} else {
int k=t->ro[]->rap<t->ro[]->rap?:;
play(t,k);
Delete(t->ro[k],x);
}
}
else Delete(t->ro[d],x);
if (t!=RR) t->rub();
}
int Kth(Treap *t,int k){
int cm=;
if (t->ro[]) cm=t->ro[]->siz;
cm++;
if (cm==k)
return t->key;
if (cm>k) return Kth(t->ro[],k);
return Kth(t->ro[],k-cm);
}
int Rank(Treap *t,int k){
int r;
if (!t) return inf;
if (t->ro[]==RR)
r=;else r=t->ro[]->siz;
if(k==t->key) return min(r+,Rank(t->ro[],k));
if(k<t->key)
return Rank(t->ro[],k);
return r++Rank(t->ro[],k);
}
int Pre(Treap *t,int k){
if (!t) return -inf;
if (k>t->key) return max(t->key,Pre(t->ro[],k));
return Pre(t->ro[],k);
}
int Sub(Treap *t,int k){
if (!t) return inf;
if (k<t->key) return min(t->key,Sub(t->ro[],k));
return Sub(t->ro[],k);
}
int n,op,x;
int main () {
freopen("a.in","r",stdin);
read(n);
Treap* root=RR;
while (n--) {
read(op); read(x);
switch(op){
case :Insert(root,x);break;
case :Delete(root,x);break;
case :printf("%d\n",Rank(root,x));break;
case :printf("%d\n",Kth(root,x));break;
case :printf("%d\n",Pre(root,x));break;
case :printf("%d\n",Sub(root,x));break;
}
// cout<<op<<endl;
}
return ;
}
朴素的treap的更多相关文章
- 无旋Treap - BZOJ1014火星人 & 可持久化版文艺平衡树
!前置技能&概念! 二叉搜索树 一棵二叉树,对于任意子树,满足左子树中的任意节点对应元素小于根的对应元素,右子树中的任意节点对应元素大于根对应元素.换言之,就是满足中序遍历为依次访问节点对应元 ...
- BZOJ 3262(Treap+树状数组)
题面 传送门 分析 分三维考虑 对第一维,直接排序 对第二维和第三维,我们这样考虑 朴素的方法是建k棵Treap,第i棵Treap里存第二维值为k的第三维数值 每次查询一组(a,b,c),只要在1~b ...
- fhq treap最终模板
新学习了fhq treap,厉害了 先贴个神犇的版, from memphis /* Treap[Merge,Split] by Memphis */ #include<cstdio> # ...
- BZOJ 1691: [Usaco2007 Dec]挑剔的美食家 [treap 贪心]
1691: [Usaco2007 Dec]挑剔的美食家 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 786 Solved: 391[Submit][S ...
- BZOJ 1862: [Zjoi2006]GameZ游戏排名系统 [treap hash]
1862: [Zjoi2006]GameZ游戏排名系统 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1318 Solved: 498[Submit][ ...
- 非旋treap模板
bzoj3580 非旋转treap 在大神教导下发现split一段区间时先split右边再split左边比较好写 #include <cstdio> #include <cstdli ...
- 朴素贝叶斯算法下的情感分析——C#编程实现
这篇文章做了什么 朴素贝叶斯算法是机器学习中非常重要的分类算法,用途十分广泛,如垃圾邮件处理等.而情感分析(Sentiment Analysis)是自然语言处理(Natural Language Pr ...
- 朴素贝叶斯(NB)复习总结
摘要: 1.算法概述 2.算法推导 3.算法特性及优缺点 4.注意事项 5.实现和具体例子 6.适用场合 内容: 1.算法概述 贝叶斯分类算法是统计学的一种分类方法,其分类原理就是利用贝叶斯公式根据某 ...
- scikit-learn 朴素贝叶斯类库使用小结
之前在朴素贝叶斯算法原理小结这篇文章中,对朴素贝叶斯分类算法的原理做了一个总结.这里我们就从实战的角度来看朴素贝叶斯类库.重点讲述scikit-learn 朴素贝叶斯类库的使用要点和参数选择. 1. ...
随机推荐
- stm32串口接收中断协议解析
借鉴了文章:<stm32串口中断接收方式详细比较> 文章地址:http://blog.csdn.net/kevinhg/article/details/40186169 串口的配置这里不做 ...
- docker、oci、runc以及kubernetes梳理
容器无疑是近年来云计算中最火热的关键词.随着docker的大热,docker.oci.runc.containerd等等名词也逐渐传播开来.这么多的名词,也容易让人混淆.本文对相关名词和其之间的联系进 ...
- YiShop_商城网站建设应该注意什么
现在电子商务迅速发展,而专门搭建商城网站的第三方开发商也很多.现在搭建一个商城网站容易,如何运营一个商城网站才是重点.下面就由YiShop说说电子商城网站建设要思考什么呢(1)建设网站的目的是什么首先 ...
- 关于hue安装后出现KeyError: "Couldn't get user id for user hue"的解决方法
首先说明出现此问题的原因是因为你使用的root用户安装了hue,然后在root用户下使用的build/env/bin/supervisor,如下图所示那样: 知道了原因,就容易解决问题了.首先要创建个 ...
- node.js第二天之模块
一.模块的定义 1.在Node.js中,以模块为单位划分所有功能,并且提供了一个完整的模块加载机制,这时的我们可以将应用程序划分为各个不同的部分. 2.狭义的说,每一个JavaScript文件都是一个 ...
- MySQL数据库数据信息迁移
环境内核信息: [root@zabbix-01 ~]# uname -a Linux lodboyedu-01 2.6.32-696.el6.x86_64 #1 SMP Tue Mar 21 19:2 ...
- 从头认识Spring-2.7 自己主动检測Bean(2)-过滤器<context:include-filter/>
这一章节我们来讨论一下过滤器<context:include-filter/>的使用. 1.domain Person接口: package com.raylee.my_new_sprin ...
- UVA 11324 The Largest Clique(强连通分量+缩点DAG的DP)
题意:给定一个有向图,求出一个最大的结点集,这个节点集中的随意两个点之间至少一个能到达还有一个点. 思路:假设一个点在这个节点集中,那么它所在的强连通分量中的点一定所有在这个节点集中,反之亦然, 求出 ...
- 一、Spring Cloud介绍
springcloud 介绍 研究了一段时间spring boot了准备向spirng cloud进发,公司架构和项目也全面拥抱了Spring Cloud.在使用了一段时间后发现Spring Clou ...
- tomcat启动失败的一种可能性
今天搭建一个新的项目,采用spring+hibernate框架,项目框架搭建完成以后,启动tomcat,报错,如下图. 第一反应是tomcat的问题,于是clean了tomcat,没用,再把tomca ...