http://www.lydsy.com/JudgeOnline/problem.php?id=3224 (题目链接)

题意

  1. 插入x数;2. 删除x数(若有多个相同的数,因只删除一个);3. 查询x数的排名(若有多个相同的数,因输出最小的排名);4. 查询排名为x的数;5. 求x的前驱(前驱定义为小于x,且最大的数);6. 求x的后继(后继定义为大于x,且最小的数)

Solution

  treap板子。右转光勋总结→_→:平衡树

细节

  一个节点还统计了这个数出现了几次,然后询问排名前驱后继什么的写的我蛋都要碎了T_T,所以这里旋转版的rank求的是小于$x$的数的个数,而不是$x$的排名。

旋转treap

// bzoj3224
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define inf 2147483640
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout)
using namespace std; const int maxn=100010;
int n,sz,Dargen;
struct node {
int son[2],size,val,rnd,w;
int& operator [] (int x) {return son[x];}
}tr[maxn]; void pushup(int k) {
tr[k].size=tr[tr[k][0]].size+tr[tr[k][1]].size+tr[k].w;
}
void rotate(int &x,int p) { //记得&
int y=tr[x][p];
tr[x][p]=tr[y][p^1];tr[y][p^1]=x;x=y; //记得写x=y
pushup(tr[y][p^1]);pushup(y);
}
void insert(int &k,int x) {
if (!k) {tr[k=++sz].val=x;tr[k].rnd=rand();tr[k].size=tr[k].w=1;return;}
int p=x>tr[k].val;tr[k].size++;
if (tr[k].val==x) {tr[k].w++;return;}
insert(tr[k][p],x);
if (tr[tr[k][p]].rnd>tr[k].rnd) rotate(k,p);
}
void erase(int &k,int x) {
if (k==0) return;
if (tr[k].val==x) {
if (tr[k].w>1) {tr[k].w--;tr[k].size--;return;}
if (tr[k][0]*tr[k][1]==0) k=tr[k][0]+tr[k][1];
else rotate(k,tr[tr[k][0]].rnd<tr[tr[k][1]].rnd),erase(k,x);
}
else tr[k].size--,erase(tr[k][x>tr[k].val],x);
}
int find(int k,int x) {
if (!k) return 0;
if (tr[tr[k][0]].size<x && x<=tr[tr[k][0]].size+tr[k].w) return tr[k].val;
else if (x<=tr[tr[k][0]].size) return find(tr[k][0],x);
else return find(tr[k][1],x-tr[tr[k][0]].size-tr[k].w);
}
int rank(int k,int x) {
if (!k) return 0;
if (x<=tr[k].val) return rank(tr[k][0],x);
else return rank(tr[k][1],x)+tr[tr[k][0]].size+tr[k].w;
}
int main() {
scanf("%d",&n);
for (int op,x,i=1;i<=n;i++) {
scanf("%d%d",&op,&x);
if (op==1) insert(Dargen,x);
if (op==2) erase(Dargen,x);
if (op==3) printf("%d\n",rank(Dargen,x)+1);
if (op==4) printf("%d\n",find(Dargen,x));
if (op==5) printf("%d\n",find(Dargen,rank(Dargen,x)));
if (op==6) printf("%d\n",find(Dargen,rank(Dargen,x+1)+1));
}
return 0;
}

非旋转treap

// bzoj3224
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define inf 2147483640
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std; const int maxn=100010;
int n,sz,Dargen;
struct node {
int son[2],size,val,rnd;
int& operator [] (int x) {return son[x];}
}tr[maxn]; void pushup(int k) {
tr[k].size=tr[tr[k][0]].size+tr[tr[k][1]].size+1;
}
void split(int k,int x,int &a,int &b) {
if (!x) {a=0;b=k;return;}
int l=tr[k][0],r=tr[k][1];
if (tr[l].size==x) tr[k][0]=0,a=l,b=k;
else if (tr[l].size+1==x) tr[k][1]=0,a=k,b=r;
else if (x<tr[l].size) split(l,x,a,tr[k][0]),b=k;
else split(r,x-tr[l].size-1,tr[k][1],b),a=k;
pushup(k);
}
int merge(int x,int y) { //按顺序x<y
if (!x || !y) return x|y;
if (tr[x].rnd>tr[y].rnd) {
tr[x][1]=merge(tr[x][1],y);
pushup(x);return x;
}
else {
tr[y][0]=merge(x,tr[y][0]);
pushup(y);return y;
}
}
int rank(int k,int x) {
if (!k) return 1;
if (x<=tr[k].val) return rank(tr[k][0],x);
else return rank(tr[k][1],x)+tr[tr[k][0]].size+1;
}
int find(int k,int x) {
if (!k) return 0;
if (tr[tr[k][0]].size+1==x) return tr[k].val;
else if (x<=tr[tr[k][0]].size) return find(tr[k][0],x);
else return find(tr[k][1],x-tr[tr[k][0]].size-1);
}
void insert(int x) {
int l,r;
tr[++sz].val=x;tr[sz].rnd=rand();tr[sz].size=1;
split(Dargen,rank(Dargen,x)-1,l,r);
Dargen=merge(merge(l,sz),r);
}
void erase(int k) {
int x,y;
split(Dargen,k,x,y);
split(x,k-1,x,k);
Dargen=merge(x,y);
}
int main() {
scanf("%d",&n);
for (int op,x,i=1;i<=n;i++) {
scanf("%d%d",&op,&x);
if (op==1) insert(x);
if (op==2) erase(rank(Dargen,x));
if (op==3) printf("%d\n",rank(Dargen,x));
if (op==4) printf("%d\n",find(Dargen,x));
if (op==5) printf("%d\n",find(Dargen,rank(Dargen,x)-1));
if (op==6) printf("%d\n",find(Dargen,rank(Dargen,x+1)));
}
return 0;
}

【bzoj3224】 Tyvj1728—普通平衡树的更多相关文章

  1. 初学 Size Balanced Tree(bzoj3224 tyvj1728 普通平衡树)

    SBT(Size Balance Tree), 即一种通过子树大小(size)保持平衡的BST SBT的基本性质是:每个节点的size大小必须大于等于其兄弟的儿子的size大小: 当我们插入或者删除一 ...

  2. [Bzoj3224][Tyvj1728] 普通平衡树(splay/无旋Treap)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3224 平衡树入门题,学习学习. splay(学习yyb巨佬) #include<b ...

  3. [bzoj3224][tyvj1728][普通平衡树] (pb_ds库自带红黑树)

    Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 1. 插入x数 2. 删除x数(若有多个相同的数,因只删除一个) 3. 查询x数的排名(若有多个相 ...

  4. [BZOJ3224/Tyvj1728]普通平衡树

    本篇博客有详细题解,浅谈算法--splay

  5. tyvj1728 普通平衡树

    为了彻底理解树状数组,试着用树状数组做了下普通平衡树 而树状数组只能离线做,或者保证值的大小在数组可承受的范围内也是可以的,因为要求离线是因为必须事前对所有数离散化. 然后我们看刘汝佳蓝书上的图 利用 ...

  6. [bzoj3196][tyvj1728]普通平衡树

    真是太差了,到现在才打出一个平衡树的板子.. 感谢blackjack大佬提供的数组版treap板子!!基本完全照搬,blackjack太神啦! 但目前我只会这几个最基本的操作(说白了STL的(mult ...

  7. 【BZOJ3224】普通平衡树(splay)

    题意: 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数,因输出最小的排 ...

  8. BZOJ3224/LOJ104 普通平衡树 pb_ds库自带红黑树

    您需要写一种数据结构,来维护一些数,其中需要提供以下操作:1. 插入x2. 删除x(若有多个相同的数,因只删除一个)3. 查询x的排名(若有多个相同的数,因输出最小的排名)4. 查询排名为x的数5. ...

  9. BZOJ3224/LOJ104 普通平衡树 treap(树堆)

    您需要写一种数据结构,来维护一些数,其中需要提供以下操作:1. 插入x2. 删除x(若有多个相同的数,因只删除一个)3. 查询x的排名(若有多个相同的数,因输出最小的排名)4. 查询排名为x的数5. ...

随机推荐

  1. SqlServer执行大的数据库脚本出错解决方法

    如果执行线上项目拷下来sqlserver的.sql的数据库脚本文件,如果文件较大时,那么就会报错内存不足之类的. 这时可以在命令提示符使用命令来执行脚本文件.切记,执行前先改一下数据库存放位置! 命令 ...

  2. UML类图(Unified Modeling Language Class Diagrams)

    统一建模语言(UML) |  类图 什么是UML? UML是一种用于可视化描述系统,具有广泛用途的建模语言.作为一种标准化的图形语言,在软件工业中被用于软件系统部件的具体化,可视化,结构化描述以及撰写 ...

  3. Python基础之公共方法

    公共方法:就是列表,元组,字典,字符串能共同使用的方法: Python内置函数 内置函数罗列 函数 描述 备注 len(item) 计算容器中的元素个数 del(item) 删除变量 del有两种方法 ...

  4. 20155229《网络对抗技术》Exp3:免杀原理与实践

    实验预习 免杀: 看为一种能使病毒木马避免被杀毒软件查杀的技术. 免杀的分类: 开源免杀:指在有病毒.木马源代码的前提下,通过修改源代码进行免杀.. 手工免杀:指在仅有病毒.木马的可执行文件(.exe ...

  5. POJ 3278&&2049&&3083

    这次的题目叫图的深度&&广度优先遍历. 然后等我做完了题发现这是DFS&&BFS爆搜专题. 3278:题目是经典的FJ,他要抓奶牛.他和牛(只有一头)在一条数轴上,他们 ...

  6. 在sourceinsight中添加快速注释 Ctrl+/

    1.搜索文件:utils.em(C:\Program Files (x86)\Source Insight 3)2.用sourceinsight打开文件:utils.em3.在文件末尾添加下面代码 m ...

  7. 蓝牙inquiry流程之HCI_Inquiry_Result_With_RSSI和HCI Extended Inquiry Result处理

    首先介绍一下和inquiry的相关的流程. inquiry是从协议栈下发的一个HCI命令.其格式如下: 这里简单介绍下第二个参数,是inquiry的持续时间, 从上图看出 inquiry持续的时间是 ...

  8. python中获取执行脚本路径方法

    1.sys.path[0]:获取执行脚本目录绝对路径 #每次执行脚本时,python会将执行脚本目录加入PYTHONPATH环境变量中(sys.path获取) #!/usr/bin/python3 i ...

  9. sqlyog mysql 外键引用列找不到想要的字段的原因

    这是因为引用列必须为一个主键才行

  10. Visual Studio控制台程序输出窗口一闪而过的解决方法

    转载大牛的博客,自己也遇到了类似的问题,解决方法很详细,也很管用   刚接触 Visual Studio的时候大多数人会写个Hello World的程序试一下,有的人会发现执行结束后输出窗口会一闪而过 ...