【学习笔记】splay入门(更新中)
声明:本博客所有随笔都参照了网络资料或其他博客,仅为博主想加深理解而写,如有疑问欢迎与博主讨论✧。٩(ˊᗜˋ)و✧*。
前言
终于学习了 spaly \(splay\) !听说了很久,因为dalao总是那这个开玩笑所以对它有深深的恐惧...但是学起来没有那么难啦,可能是因为提前学了替罪羊树?(学替罪羊树真的是痛苦555)
模板
固定变量:
\(edge\) - 这个节点的值
\(tot\) - 这个节点重复的数
\(son[0/1]\) - 左儿子右儿子
\(fa\) - 节点的父亲
\(size\) - 子树的大小
struct ndoe{
int tot, size, son[2], fa, edge;
}tree[N];
add(x)(添加一个点):
1.找到特殊点
2.判断 \(x\) 与特殊节点的值
\ \ 1)相等,则直接 \(++ \ tot\)
\ \ 2)不相等,则新建节点,更新变量
void add(int x)
{
int u = root, fa = 0;
while(u && tree[u].edge != x)
fa = u, u = tree[u].son[x > tree[u].edge];
if(u) ++ tree[u].tot;
else
{
u = ++ num;
if(fa) tree[fa].son[x > tree[fa].edge] = u;
tree[u].edge = x, tree[u].size = tree[u].tot = 1, tree[u].fa = fa;
}
splay(u, 0);
}
del(x)(删除一个点):
1.找到 \(x\) 的前驱后继
2.把前驱 \(splay\) 至根节点,把后继 \(splay\) 成前驱的儿子
3.此时后继的左儿子则为要删除的点,判断此节点的个数
\ \ 1)个数大于一则只用去掉一个,然后 \(splay\)
\ \ 2)个数为一则直接删掉
void del(int x)
{
int xpre = next(x, 0), xnxt = next(x, 1);
splay(xpre, 0), splay(xnxt, xpre);
int u = tree[xnxt].son[0];
if(tree[u].tot > 1) -- tree[u].tot, splay(u, 0);
else tree[xnxt].son[0] = 0;
}
splay(x, goal)(将 \(x\) 旋成 \(goal\) 的儿子):
1.判断 \(x\) 是否是 \(goal\) 的儿子
\ \ 1)不是,则判断 \(x\) 和它的父亲、祖先是否在一条线上,进行不同的 \(splay\)
\ \ 2)是,判断 \(x\) 是否是根并更新
void splay(int x, int goal)
{
while(tree[x].fa != goal)
{
int y = tree[x].fa, z = tree[y].fa;
if(z != goal) ((tree[z].son[0] == y) ^ (tree[y].son[0] == x)) ? rotate(x) : rotate(y);
rotate(x);
}
if(! goal) root = x;
}
rotate(x)(单旋):
1.更新 \(x\) 和 \(z\) 的父子关系
2.更新 \(y\) 和 ( \(x\) 原来和 \(y\) 对应的那个儿子)的父子关系
3.更新 \(x\) 和 \(y\) 的父子关系
4.\(update \ x、y\)
void rotate(int x)
{
int y = tree[x].fa, z = tree[y].fa, k = (tree[y].son[1] == x);
tree[z].son[tree[z].son[1] == y] = x, tree[x].fa = z;
tree[y].son[k] = tree[x].son[k ^ 1], tree[tree[x].son[k ^ 1]].fa = y;
tree[x].son[k ^ 1] = y, tree[y].fa = x;
update(y), update(x);
}
pre(x)(前驱):
1.将 \(x\) 变为树根
2.有左子树则进入左子树,没有则代表没有比它小的数了
3.进入左子树后一路往右子树上凑(找最大的)
nxt(x)(后继):
1.将 \(x\) 变为树根
2.有右子树则进入右子树,没有则代表没有比它大的数了
3.进入右子树后一路往左子树上凑(找最小的)
int next(int x, int f)//我把pre和nxt写到一起啦,实际上是一样的
{
find(x);
int u = root;
if((tree[u].edge > x && f) || (tree[u].edge < x && (! f))) return u;
u = tree[u].son[f];
while(tree[u].son[f ^ 1]) u = tree[u].son[f ^ 1];
return u;
}
find(x)(辅助函数):
1.找到值等于 \(x\) 的那个节点
2.将节点旋转至树根
void find(int x)
{
int u = root;
if(! u) return;
while(tree[u].son[x > tree[u].edge] && tree[u].edge != x)
u = tree[u].son[x > tree[u].edge];
splay(u, 0);
}
query(x)(第k大的数):
1.先判断整个树的 \(size\) 是否大于等于 \(x\),若没有则不存在
2.分三种情况继续讨论:
\ \ 1)左子树 \(size\) 大于 \(x\) ,前往左子树
\ \ 2)左子树+这个节点的数的个数大于 \(x\),则直接返回这个节点的值
\ \ 3)更新 \(x\),前往右子树
int query(int x)
{
int u = root;
if(tree[u].size < x) return 0;
while(1)
{
int y = tree[u].son[0];
if(x <= tree[y].size) u = y;
else if(x <= tree[y].size + tree[u].tot) return tree[u].edge;
else x -= (tree[y].size + tree[u].tot), u = tree[u].son[1];
}
}
【学习笔记】splay入门(更新中)的更多相关文章
- 【转】git 学习笔记( 随时更新中…… 最后更新日期201304281518)--不错
原文网址:http://blog.csdn.net/yasin_lee/article/details/5975070 GIT 是版本管理的未来! 推荐几个GIT教程网站 http://www-c ...
- Oracle 9i & 10g编程艺术-深入数据库体系结构-学习笔记(持续更新中)
--20170322 --1.0 --更新表的统计信息begin dbms_stats.set_table_stats(user,'EMP',numrows => 10000);end; beg ...
- HTML5学习笔记(持续更新中....)
平时的工作中,不知不觉我们应用了很多HTML5,但当正儿八经问起来你对HTML5了解多少,很多时候都有点懵. 做个简单的HTML5总结.包括简介.要学的知识点.凌乱的知识点 HMTL5简介 定义:ht ...
- Gradle项目构建工具学习笔记(持续更新中。。。)
1.gradle的安装 1)从官网下载gradle,然后解压 2)在系统环境变量新建GRADLE_HOME 3)将%GRADLE_HOME%\bin加入PATH中 2.验证是否安装成功 gradle ...
- [斜率优化DP]【学习笔记】【更新中】
参考资料: 1.元旦集训的课件已经很好了 http://files.cnblogs.com/files/candy99/dp.pdf 2.http://www.cnblogs.com/MashiroS ...
- python学习笔记--Django入门四 管理站点--二
接上一节 python学习笔记--Django入门四 管理站点 设置字段可选 编辑Book模块在email字段上加上blank=True,指定email字段为可选,代码如下: class Autho ...
- DBFlow框架的学习笔记之入门
什么是DBFlow? dbflow是一款android高性的ORM数据库.可以使用在进行项目中有关数据库的操作.github下载源码 1.环境配置 先导入 apt plugin库到你的classpat ...
- MongoDB学习笔记:快速入门
MongoDB学习笔记:快速入门 一.MongoDB 简介 MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统.在高负载的情况下,添加更多的节点,可以保证服务器性能.M ...
- HTML语言学习笔记(会更新)
# HTML语言学习笔记(会更新) 一个html文件是由一系列的元素和标签组成的. 标签: 1.<html></html> 表示该文件为超文本标记语言(HTML)编写的.成对出 ...
- WebSocket学习笔记——无痛入门
WebSocket学习笔记——无痛入门 标签: websocket 2014-04-09 22:05 4987人阅读 评论(1) 收藏 举报 分类: 物联网学习笔记(37) 版权声明:本文为博主原 ...
随机推荐
- Building Applications with Force.com and VisualForce(Dev401)(十七):Data Management: Data management Tools
ev401-018:Data Management: Data management ToolsModule Objectives1.List objects exposed in the impor ...
- tf.contrib.legacy_seq2seq.basic_rnn_seq2seq 函数 example 最简单实现
tf.contrib.legacy_seq2seq.basic_rnn_seq2seq 函数 example 最简单实现 函数文档:https://www.tensorflow.org/api_doc ...
- JRebel 破解使用
步骤1:生成一个GUID:在线生成GUID地址 步骤2: 根据反向代理服务器地址拼接激活地址 服务器地址: https://jrebel.qekang.com/{GUID} 如果失效刷新GUID替换就 ...
- coding++:TransactionDefinition 接口介绍
TransactionDefinition类结构: 作用: 1.TransactionDefinition接口被用于Spring事物支持的核心PlatformTransactionManager接口, ...
- Python python 五种数据类型--元组
# 定义一个元组 var1 = ('Hello','Python') var2 = tuple() print(type(var1)) #<class 'tuple'> print(typ ...
- C#算法实现获取树的高度
我们知道,树类型作为数据结构中的重要一员,树的很多实现都是来自递归.本文想要实现的就是在桌面客户端项目开发中,经常用到的树结构(.Net平台下有个控件为TreeView).事实上,我们可能因业务需求自 ...
- MySql查询当天、本周、本月、本季度、本年的数据
1.今天 SELECT * FROM 表名 WHERE TO_DAYS(时间字段名) = TO_DAYS(NOW()); 2.昨天 ; 3.本周 SELECT * FROM 表名 WHERE YEAR ...
- [noip模拟赛]虫洞holes<SPFA>
虫洞(holes.cpp/c/pas) [题目描述] N个虫洞,M条单向跃迁路径.从一个虫洞沿跃迁路径到另一个虫洞需要消耗一定量的燃料和1单位时间.虫洞有白洞和黑洞之分.设一条跃迁路径两端的虫洞质量差 ...
- 【纯净镜像】原版Windows7集成USB3.0+NVME补丁+UEFI引导旗舰版下载
系统简述: 1. 基于MSDN原版Windows7 Ultimate With SP1系统制作,无任何插件和垃圾软件. 2. 系统集成IE11浏览器,装完系统后默认浏览器就是IE11. 3.系统注入了 ...
- K-Folds cross-validator-K折交叉验证实现
源码: import numpy as np from sklearn.model_selection import KFold X = np.array([[, ], [, ], [, ], [, ...