[模板] 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* ...
随机推荐
- maven中添加json-lib的jar包
在maven配置文件pom.xml中添加如下配置信息: <dependency> <groupId>net.sf.json-lib</groupId> <ar ...
- rake db:migrate 与 bundle exec rake db:migrate 的区别(copy)
[说明:资料来自http://blog.csdn.net/lihuan974683978/article/details/8715414] 之前一直没弄明白rake db:migrate 与 bun ...
- UVa 12709 && UVaLive 6650 Falling Ants (水题)
题意:给定 n 个长方体的长,宽,高,让你求高最大的时候体积最大是多少. 析:排序,用高和体积排序就好. 代码如下: #pragma comment(linker, "/STACK:1024 ...
- linux下解压tgz文件(转载)
转自:http://www.blogjava.net/chenlb/archive/2008/09/03/226654.html .tgz 解压: tar zxvf myfile.tgz
- bzoj 4137 [FJOI2015]火星商店问题【CDQ分治+可持久化trie】
其实我不太清楚这个应该叫CDQ分治还是整体二分 参考:http://blog.csdn.net/lvzelong2014/article/details/78688727 一眼做法是线段树套可持久化t ...
- 标准字符cp功能
#include<stdio.h> #include<fcntl.h> int main(int argc,char *argv[]) { FILE *src_fp,*des_ ...
- PHP arrray_filter(), array_map()区别与应用
array_filter()用回调函数过滤数组中的元素.依次将数组中的元素传递给回调函数,如果回调函数返回true,则被过滤的元素作为返回数组的元素,并最终一起返回.数组的键名保持不变.array_m ...
- _bzoj1061 [Noi2008]志愿者招募【最小费用最大流】
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1061 尽管不是mcmf的裸题,但还是保存一下模版叭~ 很好的一道建模的题,把变量间的加加减减 ...
- 手把手教你玩微信小程序跳一跳
最近微信小程序火的半边天都红了,虽然不会写,但是至少也可以仿照网上大神开发外挂吧!下面手把手教妹纸们(汉纸们请自觉的眼观耳听)怎么愉快的在微信小游戏中获得高分. 废话不多说,咱们这就发车了!呸!咱们这 ...
- dubbo服务端响应超时错误一例记录
错误描述: Portlet J2AppsPortlet::QuickStartPortlet not available: Waiting server-side response timeout. ...