[模板] 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* ...
随机推荐
- Html.PartialView(),html.Renderpartial,html.action.html.RenderAction 辅助方法
Html.Partial(), 返回HTML字符串 .参数为部分视图 html.RenderPartial(),不返回返回HTML字符串 ,直接输出响应流.参数为部分视图 一般用于主视图中已经存在了这 ...
- 开源可扩展的Web视频播放器:Clappr Player
http://www.open-open.com/lib/view/open1417057033846.html http://www.csdn.net/article/2014-11-27/2822 ...
- arcgis for silverlight 鼠标点击地图获取当前经纬度
silverlight代码: 地图的name值是myMap.后台在页面初始化的时候,添加地图的点击事件 myMap.MouseClick+=new EventHandler<Map.MouseE ...
- 版本控制系统Git
常用的版本控制系统有VSS.SVN.CVS等等,Git是最近几年使用得比较多的分布式版本控制系统,存在即合理,Git的出现总有它出现的理由,以前的版本控制系统肯定有一些不足的地方,所以才出现了Git. ...
- 关于浮动与清浮动 float
浮动常见的几种属性值 float {left; right; none; } 主要是定义元素朝哪个方向浮动: 元素浮动后的特性 在一行显示,父级的宽度放不下,自己折行: 支持宽高等样式: 不设置 ...
- GDI+ 加载PNG图片
#include <GdiPlus.h>#pragma comment(lib, "GdiPlus.lib")using namespace Gdiplus; clas ...
- That Nice Euler Circuit UVALive - 3263 || 欧拉公式
欧拉定理: 简单多面体的顶点数V.棱数E及面数F间有关系有著名的欧拉公式:V-E+F=2. 设G为任意的连通的平面图,则v-e+f=2,v是G的顶点数,e是G的边数,f是G的面数.(引) 证明(?) ...
- 题解报告:hdu 4907 Task schedule
Problem Description 有一台机器,并且给你这台机器的工作表,工作表上有n个任务,机器在ti时间执行第i个任务,1秒即可完成1个任务.有m个询问,每个询问有一个数字q,表示如果在q时间 ...
- 419 Battleships in a Board 甲板上的战舰
给定一个二维的甲板, 请计算其中有多少艘战舰. 战舰用 'X'表示,空位用 '.'表示. 你需要遵守以下规则: 给你一个有效的甲板,仅由战舰或者空位组成. 战舰只能水平或者垂直放置.换句话 ...
- LD_LIBRARY_PATH与-L的关系以及延伸
最近跟同学讨论c++在编译时g++ -L.. 和LD_LIBRARY_PATH的问题,今天在做一个东西的时候发现,我对这两个东西的理解是错误的,经过一番研究,写下我对这些东西的想法,如果有不对的地方, ...