1. 插入x
  2. 删除x
  3. 查询排名为x的数
  4. 查询x的排名
  5. 求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的更多相关文章

  1. 模板——Treap

    不得不说平衡树博大精深,除了Treap,还有splay,非旋Treap和可持久化数据结构,今天先讲讲Treap,也很感谢这位大佬的博客给予我帮助:http://www.360doc.com/conte ...

  2. 模板—treap

    #include<iostream> #include<cstdio> #include<cstdlib> #define INF 0x7fffffff using ...

  3. 模板——Treap实现名次树

    Treap 是一种通过赋予结点随机权值的一种满足堆性质的二叉搜索树,它很好的解决了二叉搜索树顺序插入组成链式的局限性. 名次树是指在treap的每个结点中添加附加域size,表示以它为根的子树的总结点 ...

  4. LG3369 普通平衡树

    题意 维护一些数,其中需要提供以下操作: 1.插入\(x\) 2.删除\(x\)(若有多个相同的数,只删除一个) 3.查询\(x\)的排名(排名定义为比当前数小的数的个数\(+1\)) 4.查询排名为 ...

  5. treap树模板

    ///treap树模板 typedef struct Node ///节点的结构体 { Node *l,*r; int val,pri; ///节点的值和优先级 int sz; ///节点子树的节点数 ...

  6. BZOJ 3224 TYVJ 1728 普通平衡树 [Treap树模板]

    3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 7390  Solved: 3122 [Submit][S ...

  7. 三大平衡树(Treap + Splay + SBT)总结+模板[转]

    Treap树 核心是 利用随机数的二叉排序树的各种操作复杂度平均为O(lgn) Treap模板: #include <cstdio> #include <cstring> #i ...

  8. treap完全版模板

    这是我综合poj1442 3481 2352的treap操作 得到treap完全版模板.(经测AC) 结构体Tree { int key; //键值 int size; //该子树总节点个数 int ...

  9. Treap 模板 poj1442&hdu4557

    原理可以看hihocoder上面的讲解,很清楚,不多说了. 模板抄lrj训练指南上面的. /** Treap 实现 名次树 功能: 1.找到排名为k的元素 2.值为x的元素的名次 初始化:Node* ...

随机推荐

  1. 02_电话拨号器intent说明

    怎么在第一个Activity打开第二个Activity?在一个Activity中打开另外一个Activity,实际上之前已经做过,就是电话拨号器. package com.itheima.callne ...

  2. Gym 100531J Joy of Flight (几何)

    题意:你从开始坐标到末尾坐标,要经过 k 秒,然后给你每秒的风向,和飞机的最大速度,问能不能从开始到末尾. 析:首先这个风向是不确定的,所以我们先排除风向的影响,然后算出,静风是的最小速度,如果这都大 ...

  3. 【黑金教程笔记之003】【建模篇】【Lab 02 闪耀灯和流水灯】—笔记

    (1)       扫描频率和闪耀频率? 模块: /**************************************** module name:flash_module function ...

  4. E20180224-hm-xa

    separator n. 分离器,分离装置; 防胀器; colon n. 冒号; <解>结肠; 科郎(哥斯达黎加货币单位); semicolon  n. 分号;

  5. MySQL基础 -- 关系代数

    MySQL基础 -- 关系代数 关系代数是一种抽象的查询语言,它用对关系的运算来表达查询.  任何一种运算都是将一定的运算符作用于一定的运算对象上,得到预期的结果.所以运算对象.运算符.运算结果是运算 ...

  6. poj 2398 Toy Storage【二分+叉积】

    二分点所在区域,叉积判断左右 #include<iostream> #include<cstdio> #include<cstring> #include<a ...

  7. 洛谷 P2764 最小路径覆盖问题【匈牙利算法】

    经典二分图匹配问题.把每个点拆成两个,对于原图中的每一条边(i,j)连接(i,j+n),最小路径覆盖就是点数n-二分图最大匹配.方案直接顺着匹配dsf.. #include<iostream&g ...

  8. css覆盖select样式并添加小箭头

    .select { border-radius: 5px; border: 1px #F4A627 solid; -webkit-appearance: none;//清除默认样式 backgroun ...

  9. 原生javascript之实战 轮播图

    成品效果如下图所示: 因为博客园限制图片上传大小被我删了一些帧数,所以图片看起来会有一点卡,现实运行是不会的 搭建HTML和CSS结构 HTML代码如下: <div class="wr ...

  10. linux unzip和zip

    注:*压缩成限.zip格式文件 常用解压缩: [root@mysql test]# unzip -o test.zip -d tmp/ 将压缩文件test.zip在指定目录tmp下解压缩,如果已有相同 ...