【模板】非旋转Treap
Treap,也叫做树堆,是指有一个随机附加域满足堆的性质的二叉搜索树。
如果一棵二叉搜索树插入节点的顺序是随机的,那我们得到的二叉搜索树在大多数情况下是平衡的,期望高度是log(n).
但有些情况下我们并不能得知所有待插入节点,打乱以后再插入,这时我们需要给二叉搜索树加上一个随机附加域,并使这个随机附加域(优先级)满足堆的性质,以此来实现“乱序插入”的想法,使二叉搜索树保持平衡。
Treap可以满足的序列操作:
1,插入一个数x
2,删除一个数x
3,查询x的排名
4,查询排名为x的数
5,查询x的前驱
6,查询x的后继
Treap的基本操作
1,newnode新建节点
2,split分裂 把Treap按照权值分割为两部分
3,merge合并 把Treap的两部分进行合并
4,insert插入 把Treap按照插入的权值Val分裂为两部分,然后merge左边和新点,再merge新的左边和右边
5,delete删除 把Treap分裂两次,中间那部分不管它,把两边merge一下
- #include<cstdio>
- #include<algorithm>
- #define ls (a[u].l)
- #define rs (a[u].r)
- using namespace std;
- const int maxn=;
- int n,k,x,y,z,v,tot,root;
- struct treap{int l,r,v,rnd,size;}a[maxn];
- inline void read(int &k){
- k=; int f=; char c=getchar();
- while(c<''||c>'')c=='-'&&(f=-),c=getchar();
- while(''<=c&&c<='')k=k*+c-'',c=getchar();
- k*=f;
- }
- void newnode(int v){a[++tot]=(treap){,,v,rand()+,};}
- void update(int u){a[u].size=a[ls].size+a[rs].size+;}
- void split(int u,int k,int &x,int &y){
- if(!k){x=; y=u; return;}
- if(a[u].size==k){x=u; y=; return;}
- if(a[ls].size>=k) split(ls,k,x,ls),y=u;
- else split(rs,k-a[ls].size-,rs,y),x=u;
- update(u);
- }
- int merge(int x,int y){
- if(!(x*y)) return x+y;
- if(a[x].rnd>a[y].rnd){
- a[y].l=merge(x,a[y].l); update(y); return y;
- }
- else{
- a[x].r=merge(a[x].r,y); update(x); return x;
- }
- }
- int qrank(int u,int val){
- if(!u) return ;
- if(a[u].v>=val) return qrank(ls,val);
- return qrank(rs,val)+a[ls].size+;
- }
- int qval(int u,int k){
- if(a[ls].size+==k) return a[u].v;
- return a[ls].size>=k?qval(ls,k):qval(rs,k-a[ls].size-);
- }
- int main(){
- srand(); root=tot=; a[root].v=2e9; a[root].size=;
- read(n);
- while(n--){
- read(k); read(v);
- if(k==){//插入
- split(root,qrank(root,v),x,y);
- newnode(v); root=merge(merge(x,tot),y);
- }
- if(k==){//删除
- split(root,qrank(root,v),x,y);
- split(y,,z,y); root=merge(x,y);
- }
- if(k==) printf("%d\n",qrank(root,v)+);//查询x的排名
- if(k==) printf("%d\n",qval(root,v));//查询排名为x的数
- if(k==) printf("%d\n",qval(root,qrank(root,v)));//查询x的前驱
- if(k==) printf("%d\n",qval(root,qrank(root,v+)+));//查询x的后继
- }
- return ;
- }
- #include<cstdio>
- #include<algorithm>
- #define ls (a[u].l)
- #define rs (a[u].r)
- using namespace std;
- const int maxn=;
- int n,k,x,y,z,v,tot,root;
- struct treap{int l,r,v,rnd,size;}a[maxn];
- inline int read(){
- int k=,f=; char c=getchar();
- while(c<''||c>'')c=='-'&&(f=-),c=getchar();
- while(''<=c&&c<='')k=k*+c-'',c=getchar();
- return k*f;
- }
- void newnode(int val){a[++tot]=(treap){,,val,rand()+,};}
- void update(int u){a[u].size=a[ls].size+a[rs].size+;}
- void split(int u,int k,int &x,int &y){
- if(!k){x=; y=u; return;}
- if(a[u].size==k){x=u; y=; return;}
- if(a[ls].size>=k) split(ls,k,x,ls),y=u;
- else split(rs,k-a[ls].size-,rs,y),x=u;
- update(u);
- }
- int merge(int x,int y){
- if(!x||!y) return x+y;
- if(a[x].rnd<a[y].rnd){a[x].r=merge(a[x].r,y); update(x); return x;}
- else{a[y].l=merge(x,a[y].l); update(y); return y;}
- }
- int qrank(int u,int val){
- if(!u) return ;
- return a[u].v>=val?qrank(ls,val):qrank(rs,val)+a[ls].size+;
- }
- int qval(int u,int k){
- if(a[ls].size+==k) return a[u].v;
- return a[ls].size>=k?qval(ls,k):qval(rs,k-a[ls].size-);
- }
- int main(){
- srand(); a[root=tot=]=(treap){,,2e9,,};
- n=read();
- while(n--){
- k=read(); v=read();
- if(k==){
- split(root,qrank(root,v),x,y);
- newnode(v); root=merge(merge(x,tot),y);
- }
- if(k==){
- split(root,qrank(root,v),x,y); split(y,,z,y);
- root=merge(x,y);
- }
- if(k==) printf("%d\n",qrank(root,v)+);
- if(k==) printf("%d\n",qval(root,v));
- if(k==) printf("%d\n",qval(root,qrank(root,v)));
- if(k==) printf("%d\n",qval(root,qrank(root,v+)+));
- }
- return ;
- }
洛谷3369
【模板】非旋转Treap的更多相关文章
- BZOJ5063旅游——非旋转treap
题目描述 小奇成功打开了大科学家的电脑. 大科学家打算前往n处景点旅游,他用一个序列来维护它们之间的顺序.初 始时,序列为1,2,...,n. 接着,大科学家进行m次操作来打乱顺序.每次操作有6步: ...
- BZOJ1251序列终结者——非旋转treap
题目描述 网上有许多题,就是给定一个序列,要你支持几种操作:A.B.C.D.一看另一道题,又是一个序列 要支持几种操作:D.C.B.A.尤其是我们这里的某人,出模拟试题,居然还出了一道这样的,真是没技 ...
- 平衡树及笛卡尔树讲解(旋转treap,非旋转treap,splay,替罪羊树及可持久化)
在刷了许多道平衡树的题之后,对平衡树有了较为深入的理解,在这里和大家分享一下,希望对大家学习平衡树能有帮助. 平衡树有好多种,比如treap,splay,红黑树,STL中的set.在这里只介绍几种常用 ...
- 旋转/非旋转treap的简单操作
treap(树堆) 是在二叉搜索树的基础上,通过维护随机附加域,使其满足堆性质,从而使树相对平衡的二叉树: 为什么可以这样呢? 因为在维护堆的时候可以同时保证搜索树的性质: (比如当一棵树的一个域满足 ...
- 非旋转 treap
其实之前学过一次非旋转 treap,但是全忘光了,今天复习一下. 洛谷 P3369 [模板]普通平衡树 code: #include <bits/stdc++.h> #define N 1 ...
- [bzoj3173]最长上升子序列_非旋转Treap
最长上升子序列 bzoj-3173 题目大意:有1-n,n个数,第i次操作是将i加入到原有序列中制定的位置,后查询当前序列中最长上升子序列长度. 注释:1<=n<=10,000,开始序列为 ...
- 关于非旋转treap的学习
非旋转treap的操作基于split和merge操作,其余操作和普通平衡树一样,复杂度保证方式与旋转treap差不多,都是基于一个随机的参数,这样构出的树树高为\(logn\) split 作用:将原 ...
- [Codeforces702F]T-Shirts——非旋转treap+贪心
题目链接: Codeforces702F 题目大意:有$n$种T恤,每种有一个价格$c_{i}$和品质$q_{i}$且每种数量无限.现在有$m$个人,第$i$个人有$v_{i}$元,每人每次会买他能买 ...
- BZOJ3223文艺平衡树——非旋转treap
此为平衡树系列第二道:文艺平衡树您需要写一种数据结构,来维护一个有序数列,其中需要提供以下操作: 翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 ...
- BZOJ3224普通平衡树——非旋转treap
题目: 此为平衡树系列第一道:普通平衡树您需要写一种数据结构,来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数, ...
随机推荐
- Linux gadget驱动分析2------设备识别过程
设备连上主机之后,设备驱动做了的事. 设备连上host的port之后,主机端会有一套策略发送请求获取device的一系列描述符.进行枚举过程.找到适合该device的驱动. 这样就可以与device进 ...
- Unix域套接字(Unix Domain Socket)介绍【转】
本文转载自:http://blog.csdn.net/roland_sun/article/details/50266565 版权声明:本文为博主原创文章,未经博主允许不得转载. 在Linux系统中, ...
- 第四章、TIny4412 U-BOOT移植四 配置时钟频率源码分析【转】
本文转载自:http://blog.csdn.net/eshing/article/details/37542459 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] 上 ...
- P3959 宝藏 状压dp
之前写了一份此题关于模拟退火的方法,现在来补充一下状压dp的方法. 其实直接在dfs中状压比较好想,而且实现也很简单,但是网上有人说这种方法是错的...并不知道哪错了,但是就不写了,找了一个正解. 正 ...
- 8.3 TCPIP协议族
接下来我们要学习的内容是TCP/IP协议族.TCP/IP协议族在网络系统中是非常重要的.这一个协议族当中牵涉到许许多多的我们平常所用到的协议.TCP/IP呢它也有分层模型.然后我们讲到的就是三方面的内 ...
- Java开源JSP标签库
01displytag 与Struts结合使用最出名的一个tag主要是显示表格数据很漂亮.完善. 02cewolf tag 用来在web上显示复杂图形报表的一个jsp tag. 03Loading T ...
- Linux扩展正则表达式
1. 扩展正则表达式 1.1 +(加号) + 表示前一个字符出现1次或1次以上 1.1.1 理解+ 要求:取出文件内容连续出现的小写字母 [root@oldboyedu50-lnb /oldboy]# ...
- 页面渐进式消失【JS代码】
// 设定时间,页面慢慢变透明,直到消失 var opacityInterval = setInterval(function () { // 普通时间转为格林威治时间 var targetDate ...
- JavaScript--String 字符串对象属性
访问字符串对象的属性length: stringObject.length; 返回该字符串的长度. var mystr="Hello World!"; var myl=mystr. ...
- Educational Codeforces Round 24 题解
A: 考你会不会除法 //By SiriusRen #include <bits/stdc++.h> using namespace std; #define int long long ...