[模板] Treap
- 插入x
- 删除x
- 查询排名为x的数
- 查询x的排名
- 求x的前驱、后继
//Stay foolish,stay hungry,stay young,stay simple
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cctype>
using namespace std;
const int MAXN=100010;
const int INF=1<<29;
int rd(){
int ret=0,f=1;char c;
while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
while(isdigit(c)){
ret=ret*10+c-'0';
c=getchar();
}
return ret*f;
}
struct Treap{
int l,r;
int val,dat;
int cnt,size;
}node[MAXN];
int tcnt,root,n;
int add(int val){
node[++tcnt].val = val;
node[tcnt].dat = rand();
node[tcnt].cnt = node[tcnt].size = 1;
return tcnt;
}
void updata(int x){
node[x].size =node[node[x].l].size+node[node[x].r].size+node[x].cnt;
}
void build(){
add(-INF);add(INF);
root=1;node[1].r=2;
updata(root);
}
int GetRankByVal(int x,int val){
if(x==0) return 0;
if(val==node[x].val) return node[node[x].l].size+1;
if(val<node[x].val) return GetRankByVal(node[x].l,val);
return GetRankByVal(node[x].r,val)+node[node[x].l].size+node[x].cnt;
}
int GetValByRank(int x,int rank){
if(x==0) return INF;
if(node[node[x].l].size>=rank) return GetValByRank(node[x].l,rank);
if(node[node[x].l].size+node[x].cnt>=rank) return node[x].val;
return GetValByRank(node[x].r,rank-node[node[x].l].size-node[x].cnt);
}
void zig(int &x){
int y=node[x].l;
node[x].l=node[y].r;node[y].r=x;x=y;
updata(node[x].r);updata(x);
}
void zag(int &x){
int y=node[x].r;
node[x].r = node[y].l;node[y].l = x;x=y;
updata(node[x].l);updata(x);
}
void inst(int &x,int val){
if(x==0){
x=add(val);
return;
}
if(val==node[x].val){
node[x].cnt++;
updata(x);
return;
}
if(val<node[x].val){
inst(node[x].l,val);
if(node[x].dat<node[node[x].l].dat) zig(x);
}else{
inst(node[x].r,val);
if(node[x].dat<node[node[x].r].dat) zag(x);
}
updata(x);
}
int GetPre(int val){
int ans=1;
int x=root;
while(x){
if(val==node[x].val){
if(node[x].l>0){
x=node[x].l;
while(node[x].r>0) x=node[x].r;
ans=x;
}
break;
}
if(node[x].val<val&&node[x].val>node[ans].val) ans=x;
x=val<node[x].val?node[x].l:node[x].r;
}
return node[ans].val;//ans
}
int GetNext(int val){
int ans=2;
int x=root;
while(x){
if(val==node[x].val){
if(node[x].r>0){
x=node[x].r;
while(node[x].l>0) x=node[x].l;
ans=x;
}
break;
}
if(node[x].val>val&&node[x].val<node[ans].val) ans=x;
x=val<node[x].val?node[x].l:node[x].r;
}
return node[ans].val;
}
void remove(int &x,int val){
if(x==0) return;
if(val==node[x].val){
if(node[x].cnt>1){
node[x].cnt--;updata(x);
return;
}
if(node[x].l||node[x].r){
if(node[x].r==0||node[node[x].l].dat>node[node[x].r].dat){
zig(x),remove(node[x].r,val);
}else{
zag(x),remove(node[x].l,val);
}
updata(x);
}
else x=0;
return;
}
val<node[x].val?remove(node[x].l,val):remove(node[x].r,val);
updata(x);
}
int main(){
n=rd();
build();
while(n--){
int opt,x;
opt=rd();x=rd();
switch(opt){
case 1:
inst(root,x);
break;
case 2:
remove(root,x);
break;
case 3:
printf("%d\n",GetRankByVal(root,x)-1);
break;
case 4:
printf("%d\n",GetValByRank(root,x+1));
break;
case 5:
printf("%d\n",GetPre(x));
break;
case 6:
printf("%d\n",GetNext(x));
break;
}
}
return 0;
}
[模板] Treap的更多相关文章
- 模板——Treap
不得不说平衡树博大精深,除了Treap,还有splay,非旋Treap和可持久化数据结构,今天先讲讲Treap,也很感谢这位大佬的博客给予我帮助:http://www.360doc.com/conte ...
- 模板—treap
#include<iostream> #include<cstdio> #include<cstdlib> #define INF 0x7fffffff using ...
- 模板——Treap实现名次树
Treap 是一种通过赋予结点随机权值的一种满足堆性质的二叉搜索树,它很好的解决了二叉搜索树顺序插入组成链式的局限性. 名次树是指在treap的每个结点中添加附加域size,表示以它为根的子树的总结点 ...
- LG3369 普通平衡树
题意 维护一些数,其中需要提供以下操作: 1.插入\(x\) 2.删除\(x\)(若有多个相同的数,只删除一个) 3.查询\(x\)的排名(排名定义为比当前数小的数的个数\(+1\)) 4.查询排名为 ...
- treap树模板
///treap树模板 typedef struct Node ///节点的结构体 { Node *l,*r; int val,pri; ///节点的值和优先级 int sz; ///节点子树的节点数 ...
- BZOJ 3224 TYVJ 1728 普通平衡树 [Treap树模板]
3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 7390 Solved: 3122 [Submit][S ...
- 三大平衡树(Treap + Splay + SBT)总结+模板[转]
Treap树 核心是 利用随机数的二叉排序树的各种操作复杂度平均为O(lgn) Treap模板: #include <cstdio> #include <cstring> #i ...
- treap完全版模板
这是我综合poj1442 3481 2352的treap操作 得到treap完全版模板.(经测AC) 结构体Tree { int key; //键值 int size; //该子树总节点个数 int ...
- Treap 模板 poj1442&hdu4557
原理可以看hihocoder上面的讲解,很清楚,不多说了. 模板抄lrj训练指南上面的. /** Treap 实现 名次树 功能: 1.找到排名为k的元素 2.值为x的元素的名次 初始化:Node* ...
随机推荐
- VS2010打包回顾
1. 在vs2010 选择“新建项目”à“ 其他项目类型”à“ Visual Studio Installerà “安装项目”: 命名为:Setup1 . 这是在VS2010中将有三个文件夹, 1. ...
- Entity Framework Code First 迁移
Entity Framework CodeFirst数据迁移 http://www.cnblogs.com/aehyok/p/3325459.html Entity Framework Code Fi ...
- centos 6.2 pptp 客户端 安装(转载)
转自:http://www.lnmpblog.com/archives/611 centos 6.2 64.bit的桌面版本.配置vpn客户端. 步骤: 1.yum -y install pptp 2 ...
- Ubuntu16.0.4安装搜狗输入法
方法一: 1.进入搜狗linux输入法下载页面 2.进入下载好的文件目录,双击运行安装包(这点跟windows一样) 3.Ubuntu软件安装管理界面自动弹出,并显示安装按钮.点击就可以安装 方法二: ...
- PHP中foreach有关引用的问题
软件开发的过程中,细节处理非常重要,说得大一点就是细节决定成败,别人不懂的地方,你懂,别人没注意到的细节,你注意到了,这就是你胜出对方的地方,这样就体现出了你的价值. 下面是几个foreach循环中引 ...
- poj 3295 Tautology 伪递归
题目链接: http://poj.org/problem?id=3295 题目描述: 给一个字符串,字符串所表示的表达式中p, q, r, s, t表示变量,取值可以为1或0.K, A, N, C, ...
- 微信小程序组件解读和分析:七、button按钮
button按钮组件说明: button,顾名思义,按钮,类似于html的button标签.我们可以设置按钮的属性,比如字体颜色大小,背景颜色等,可以给按钮绑定事件,用户点击时会触发事件. butto ...
- python学习一 hello world of python
我使用的环境是 OS:Red Hat Enterprise Linux AS release 4 (Nahant Update 3) PYTHON:2.7.2 如果操作系统没有安装python, 百度 ...
- jQuery 小实例 关于按字母排序
jQuery的强大再次不再赘述 一般情况下操作表格式数据的一种最常见的任务就是排序,在一个大型的表格中,能够对要寻找的信息进行重新排列是非常重要的,一般情况用来完成排序的方式有两种 :一种是服务器端排 ...
- webstorm里直接调用命令行
写代码写到一半要切换窗口出去敲命令行?webstorm的external tools可以帮你省下一点时间 举例说明,比如我要直接使用npm: ctrl+alt+s打开setting菜单,找到exter ...