LG3369 普通平衡树
题意
维护一些数,其中需要提供以下操作:
- 1.插入\(x\)
- 2.删除\(x\)(若有多个相同的数,只删除一个)
- 3.查询\(x\)的排名(排名定义为比当前数小的数的个数\(+1\))
- 4.查询排名为\(x\)的数
- 5.求最大的小于\(x\)数
- 6.求最小的大于\(x\)数
\(n \leq 100000\)
思路
这是一道\(treap\)模板
\(Treap=tree+heap\)
下图是一棵二叉排序树

性质:若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;它的左、右子树也分别为二叉排序树。
但是有一个问题,如果被卡之后很有可能变成一棵“链”搜索树。然后堆就现身了,可以随机另外附权值,在二叉排序树基础上,它还需要满足随机权值是小根堆,这时候就需要一个旋转操作。
这样子就可以让一些链重新压扁成树,而这些旋转操作,只会影响到三个点
void cal(int x){
size[x]=size[s[x][0]]+size[s[x][1]]+1;
}
void r(int &k,int p){
int t=s[k][p];
s[k][p]=s[t][!p],s[t][!p]=k;
cal(k),cal(t);
k=t;
}
然后就可以开始进行操作了,操作就是在普通二叉树上加上旋转操作
- 1.插入:找到这个点的位置,给每个点随机一个优先级,然后如果它的优先级要小于父节点,我们就把它旋转上去。
void ins(int &k,int x){
if (!k){
k=++cnt,w[k]=x,pos[k]=rand()*rand()%19620817,size[k]=1;
return;
}
size[k]++;
if (x<=w[k]){
ins(s[k][0],x);
if(pos[s[k][0]]<pos[k]) r(k,0);
}else{
ins(s[k][1],x);
if (pos[s[k][1]]<pos[k]) r(k,1);
}
}
- 2.删除:有点像堆的删除,先看看有没有。有的话找到这个点,将这个点优先级小的子节点旋转上来,一直将其旋到叶子,然后删除。
bool f(int k,int x){
if (w[k]==x) return 1;
if (!k) return 0;
if (w[k]>x) return f(s[k][0],x);
return f(s[k][1],x);
}
void del(int &k,int x){
if (x>w[k]) del(s[k][1],x);
else if (x<w[k]) del(s[k][0],x);
else{
if (s[k][0]*s[k][1]==0) {
k=s[k][0]+s[k][1];
return;
}
if (pos[s[k][0]]<pos[s[k][1]]) {r(k,0);del(s[k][1],x);}
else {r(k,1);del(s[k][0],x);}
}
cal(k);
}
- 3.查找\(x\)的排名:只要看左右子树的大小就可以了,但是要注意一点:因为查询的是最小的排名,所以当我们查到\(x\)的时候,不能直接返回,而要递归下去,直到到达叶节点为止
int find(int k,int x){
if (!k) return 1;
if (x<=w[k]) return find(s[k][0],x);
return size[s[k][0]]+1+find(s[k][1],x);
}
- 4.查询排名为\(x\)的数:直接左右子树判一判查下去
int find2(int k,int x){
if (x-1==size[s[k][0]]) return w[k];
if (x>size[s[k][0]]) return find2(s[k][1],x-size[s[k][0]]-1);
else return find2(s[k][0],x);
}
- 5.求最大的小于\(x\)数
- 6.求最小的大于\(x\)数
两个操作非常相似,如果找到了小于\(x\)的,则还要看一看左子树还有没比\(x\)小的,否则就去右子树。
int pre(int k,int x){
if (!k) return -INF;
if (w[k]<x) return max(pre(s[k][1],x),w[k]);
return pre(s[k][0],x);
}
int Next(int k,int x){
if (!k) return INF;
if (w[k]>x) return min(w[k],Next(s[k][0],x));
return Next(s[k][1],x);
}
完整版把上面所有的合在一起就好了
LG3369 普通平衡树的更多相关文章
- 普通平衡树 lg3369
在多次学习splay后,我终于理解并码出了整份代码 参考了https://tiger0132.blog.luogu.org/slay-notes的博客 具体实现原理在上面这篇博客和百度中可以查到,接下 ...
- LG3369 【模板】普通平衡树
题意 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入x数 删除x数(若有多个相同的数,因只删除一个) 查询x数的排名(排名定义为比当前数小的数的个数+1.若有多个相 ...
- [BZOJ3223]Tyvj 1729 文艺平衡树
[BZOJ3223]Tyvj 1729 文艺平衡树 试题描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区 ...
- [BZOJ3224]Tyvj 1728 普通平衡树
[BZOJ3224]Tyvj 1728 普通平衡树 试题描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个) ...
- BZOJ3223: Tyvj 1729 文艺平衡树 [splay]
3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3595 Solved: 2029[Submit][Sta ...
- [普通平衡树treap]【学习笔记】
3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 9046 Solved: 3840[Submit][Sta ...
- BZOJ 3224: Tyvj 1728 普通平衡树
3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 9629 Solved: 4091[Submit][Sta ...
- BZOJ 3223: Tyvj 1729 文艺平衡树
3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3628 Solved: 2052[Submit][Sta ...
- 【Splay】bzoj3223-Tyvj1729文艺平衡树
一.题目 Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 ...
随机推荐
- 再说C模块的编写(2)
[前言] 在<再说C模块的编写(1)>中主要总结了Lua调用C函数时,对数组和字符串的操作,而这篇文章将重点总结如何在C函数中保存状态. 什么叫做在C函数中保存状态?比如你现在使用Lua调 ...
- OpenCV3编程入门-读书笔记1
一.OpenCV概述 1.OpenCV全程Open Source Computer Vision Library,即开源计算机视觉库.它是一个跨平台的开源计算机视觉库,可以运行在windows.lin ...
- Java实现大数加法运算的几种方法
大数加法 思路一:定义String变量str1和str2分别存储输入的两个大数,定义num1[]和num2[]两个int型数组,将两个字符串分别逐个字符逆序存入数组,定义sum[]数组存放求和结果,使 ...
- CentOS7上部署taiga项目管理软件
作者:waringid 一.简介 Taiga 是一个免费开源,而且功能非常强大的项目管理平台,用于初创企业和敏捷开发团队.提供一个简单.漂亮的项目管理工具.Taiga 采用 Python Django ...
- C#使用FileSystemWatcher控件实现的文件监控功能示例
本文实例讲述了C#使用FileSystemWatcher控件实现的文件监控功能.分享给大家供大家参考,具体如下: FileSystemWatcher 可以使用FileSystemWatcher组件监视 ...
- 一、ESP8266入门(基于LUA开发)
序 一入坑便停不下来... 还挺有意思的哈,233,,,, 资料杂,自己一个一个去找确实浪费了不少时间,而且大多还都是英文的,需要硬着头皮看. 这次实践入门,更是对英语的重要确信无疑.Github必须 ...
- Maximum Average Subarray I
https://leetcode.com/problems/maximum-average-subarray-i/#/description 求指定长度为 k 的子数组的最大均值,基本思路是用长度为k ...
- vue笔记-生命周期
生命周期钩子 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT ...
- Java笔记(二十一) 动态代理
动态代理 一.静态代理 代理的背后一般至少有一个实际对象,代理的外部功能和实际对象一般是一样的, 用户与代理打交道,不直接接触实际对象.代理存在的价值: 1)节省成本比较高的实际对象创建开销,按需延迟 ...
- [是男人就过8题——Pony.ai]Perfect N-P Arrays
[是男人就过8题--Pony.ai]Perfect N-P Arrays 题目大意: 一棵\(n(\sum n\le5\times10^6)\)个结点的树,每个结点都有一个括号.求树上一个合法的括号序 ...