模板:有旋treap
有旋转的treap,其实rotate比较难理解
没关系,上板子:
题目还是普通平衡树
#include<iostream>
#include<cstdio>
#include<algorithm>
#define MAXN 100005
using namespace std;
int n,opt,x,root=0,np;
struct node{
int ch[MAXN][2],val[MAXN],size[MAXN],cnt[MAXN],prior[MAXN];
void update(int now){
size[now]=size[ch[now][0]]+size[ch[now][1]]+cnt[now];
}
void rotate(int &now,int dir){
int son=ch[now][dir^1];
ch[now][dir^1]=ch[son][dir];
ch[son][dir]=now;
update(now);
update(now=son);
}
void insert(int &now,int x){
if(!now){
now=++np;
size[now]=cnt[now]=1;
prior[now]=rand();
val[now]=x;
return ;
}
size[now]++;
if(val[now]==x){
cnt[now]++;
return ;
}
int d=x>val[now];
insert(ch[now][d],x);
if(prior[ch[now][d]]<prior[now]) rotate(now,d^1);
}
void remove(int &now,int num){
if(!now) return;
if(val[now]==num){
if(cnt[now]>1){
size[now]--;
cnt[now]--;
return;
}
if(!ch[now][0]||!ch[now][1]){
now=ch[now][0]+ch[now][1];
return;
}
int d=prior[ch[now][1]]<prior[ch[now][0]];
rotate(now,d^1);
remove(now,num);
return;
}
size[now]--;
int d=num>val[now];
remove(ch[now][d],num);
}
int get_rank(int now, int num){
if(!now) return 0;
if(num==val[now]) return size[ch[now][0]]+1;
int d=num>val[now];
if(d) return size[ch[now][0]]+cnt[now]+get_rank(ch[now][1],num);
return get_rank(ch[now][0],num);
}
int get_k(int now,int k){
while(now){
if(k<=size[ch[now][0]]) now=ch[now][0];
else if(k>size[ch[now][0]]+cnt[now]) k-=size[ch[now][0]]+cnt[now],now=ch[now][1];
else return val[now];
}
}
int get_pre(int now,int num){
if(!now) return -0x7fffffff;
if(num<=val[now]) return get_pre(ch[now][0],num);
return max(val[now],get_pre(ch[now][1],num));
}
int get_next(int now,int num){
if(!now) return 0x7fffffff;
if(num>=val[now]) return get_next(ch[now][1],num);
return min(val[now],get_next(ch[now][0],num));
}
}treap;
int main(){
scanf("%d",&n);
while(n--){
scanf("%d%d",&opt,&x);
if(opt==1) treap.insert(root,x);
else if(opt==2) treap.remove(root, x);
else if(opt==3) printf("%d\n",treap.get_rank(root,x));
else if(opt==4) printf("%d\n",treap.get_k(root,x));
else if(opt==5) printf("%d\n",treap.get_pre(root,x));
else if(opt==6) printf("%d\n",treap.get_next(root,x));
}
return 0;
}
模板:有旋treap的更多相关文章
- 模板 - 无旋Treap
一般而言作为一棵平衡树只需要插入,删除,值求排名,排名求值,前驱,后继,六个接口. #include<bits/stdc++.h> using namespace std; typedef ...
- [模板] 无旋Treap (C++ class)
注意!本帖不是算法介绍!只是贴代码(逃) //嫌stdlib的rand太慢,手打了一个 /* Author: hotwords */ typedef unsigned int tkey; class ...
- 模板——无旋Treap
#include "bits/stdc++.h" using namespace std; inline int read(){ ,k=;char ch=getchar(); :, ...
- 平衡树简单教程及模板(splay, 替罪羊树, 非旋treap)
原文链接https://www.cnblogs.com/zhouzhendong/p/Balanced-Binary-Tree.html 注意是简单教程,不是入门教程. splay 1. 旋转: 假设 ...
- [模板] 平衡树: Splay, 非旋Treap, 替罪羊树
简介 二叉搜索树, 可以维护一个集合/序列, 同时维护节点的 \(size\), 因此可以支持 insert(v), delete(v), kth(p,k), rank(v)等操作. 另外, prev ...
- 无旋treap的简单思想以及模板
因为学了treap,不想弃坑去学splay,终于理解了无旋treap... 好像普通treap没卵用...(再次大雾) 简单说一下思想免得以后忘记.普通treap因为带旋转操作似乎没卵用,而无旋tre ...
- 模板 - 数据结构 - 可持久化无旋Treap/PersistentFHQTreap
有可能当树中有键值相同的节点时,貌似是要对Split和Merge均进行复制的,本人实测:只在Split的时候复制得到了一个WA,但只在Merge的时候复制还是AC,可能是恰好又躲过去了.有人说假如确保 ...
- 洛谷 - P3391 【模板】文艺平衡树(Splay) - 无旋Treap
https://www.luogu.org/problem/P3391 使用无旋Treap维护序列,注意的是按顺序插入的序列,所以Insert实际上简化成直接root和Merge合并,但是假如要在序列 ...
- 非旋 treap 结构体数组版(无指针)详解,有图有真相
非旋 $treap$ (FHQ treap)的简单入门 前置技能 建议在掌握普通 treap 以及 左偏堆(也就是可并堆)食用本blog 原理 以随机数维护平衡,使树高期望为logn级别, FHQ ...
- 2018.08.27 rollcall(非旋treap)
描述 初始有一个空集,依次插入N个数Ai.有M次询问Bj,表示询问第Bj个数加入集合后的排名为j的数是多少 输入 第一行是两个整数N,M 接下来一行有N个整数,Ai 接下来一行有M个整数Bj,保证数据 ...
随机推荐
- 数据提取--JSON
什么是数据提取? 简单的来说,数据提取就是从响应中获取我们想要的数据的过程 非结构化的数据:html等 结构化数据:json,xml等 处理方法:正则表达式.xpath 处理方法:转化为python数 ...
- LUOGU P3919 【模板】可持久化数组(主席树)
传送门 解题思路 给每一时刻建一棵线段树维护当前时刻的值,然后修改的时候直接修改,查询的时候直接查,记住查询完后一定要复制. 代码 #include<iostream> #include& ...
- Js 数组的各种方法及操作
一.数组去重 var arr = [0,1,20,3,0,45,6,0]; Array.prototype.unrepeat = function(){ var array = []; for(var ...
- (转)Android 升级 ADT 之后报错之一 case语句 .
转:http://blog.csdn.net/wchinaw/article/details/7325641 下面文章大意是指:在一般的Android项目中,R类的常量都是用final定义的,但ADT ...
- FastJSON实现详解
摘要:“快”作为程序员追逐的终极目标之一,而FastJSON则很好的证明了这一特性.本期<问底>,静行将带大家见证它序列化和反序列化的实现过程,一起领略它的“快”感. 还记得电影<功 ...
- SQL SERVER 备份数据库时候错误处理
当备份数据库时候出现如下错误时候 只需要删除备份目标就行了
- django零散知识点
后端将对象以对象形式传到前端: from django.core.serializers import serialize def xxx(reqeust): project_list = model ...
- JS规则 自加一,自减一 ( ++和- -) 【mynum = mynum + 1;//等同于mynum++;】
自加一,自减一 ( ++和- -) 算术操作符除了(+.-.*./)外,还有两个非常常用的操作符,自加一"++":自减一"--".首先来看一个例子: mynum ...
- 转载 pep8安装
一.前提准备 在Python安装了pip的情况下,命令行输入 pip install autopep8 二.PyCharm设置 成功之后,打开PyCharm,File-->setting--&g ...
- Java虚拟机性能管理神器 - VisualVM(8) 查找JAVA应用程序耗时的方法函数【转】
Java虚拟机性能管理神器 - VisualVM(8) 查找JAVA应用程序耗时的方法函数[转] 标签: javajvm监控工具性能优化 2015-04-07 16:47 1846人阅读 评论(0) ...