Splay 树简介

【Splay 树简介】
Treap 树解决平衡的办法是给每个结点加上一个随机的优先级,实现概率上的平衡。Splay 树直接用旋转调整树的形态,通过旋转改善树的平衡性。计算量小,效果好。
● Splay 树的旋转主要分为“
单旋”和“双旋”。
所谓“单旋”,即把结点 x 与它的父结点交换位置,使结点 x 上升一层。“单旋”不会减少树的层数,对改善平衡性没有帮助。根据旋转方向,“单旋”又分为
左旋zag)与右旋zig)。
所谓“双旋”,即两次“单旋”。“双旋”同时旋转
结点 x,父结点 f 及祖父结点 g 等3个结点,能改善平衡性。“双旋”又分为“一字旋”与“之字旋”。
● Splay 树的旋转示意图


 



 


Splay 树的基本操作是把结点旋转到树的根部,这样下次访问它时,只需查一次就 OK 了。
● Splay 树是
动态树(LCT,Link Cut Tree)与树链剖分的基础。
● Splay 树
曾经最常使用的 BST。不过,现在经常使用 FHQ Treap 树实现很多传统的 Splay 树的题目。因为,FHQ Treap 树代码更容易写,效率也很高,且可做持久化

【Splay 树算法模板】
洛谷 P6136 代码:https://www.luogu.com.cn/problem/P6136

#include<bits/stdc++.h>
using namespace std;const int maxn=1.1e6+5;
const int inf=(1<<30)+5;struct Node {int ch[2];int p,v;int size;int cnt;
} tr[maxn];int root,idx;void pushup(int u) {tr[u].size=tr[tr[u].ch[0]].size+tr[tr[u].ch[1]].size+tr[u].cnt;
}void rotate(int x) {int y=tr[x].p;int z=tr[y].p;int k=(tr[y].ch[1]==x);tr[y].ch[k]=tr[x].ch[k^1],tr[tr[x].ch[k^1]].p=y;tr[x].ch[k^1]=y,tr[y].p=x;tr[z].ch[tr[z].ch[1]==y]=x,tr[x].p=z;pushup(y);pushup(x);
}void splay(int x, int k) {while(tr[x].p!=k) {int y=tr[x].p;int z=tr[y].p;if(z!=k) {if((tr[z].ch[1]==y) ^ (tr[y].ch[1]==x)) rotate(x);else rotate(y);}rotate(x);}if(!k) root=x;
}void insert(int x) {int u=root, p=0;while(u && tr[u].v!=x) {p=u;u=tr[u].ch[x>tr[u].v];}if(u) tr[u].cnt++;else {u=++idx;if(p) tr[p].ch[x>tr[p].v]=u;tr[u].p=p;tr[u].v=x;tr[u].size=1;tr[u].cnt=1;}splay(u,0);
}void find(int x) {int u=root;while(tr[u].ch[x>tr[u].v] && tr[u].v!=x) u=tr[u].ch[x>tr[u].v];splay(u,0);
}int get_pre(int x) {find(x);if(tr[root].v<x) return root;int u=tr[root].ch[0];while(tr[u].ch[1]) u=tr[u].ch[1];splay(u,0);return u;
}int get_suc(int x) {find(x);if(tr[root].v>x) return root;int u=tr[root].ch[1];while(tr[u].ch[0]) u=tr[u].ch[0];splay(u,0);return u;
}void remove(int x) {int pre=get_pre(x);int suc=get_suc(x);splay(pre,0);splay(suc,pre);int del=tr[suc].ch[0];if(tr[del].cnt>1) tr[del].cnt--,splay(del,0);else tr[suc].ch[0]=0, splay(suc,0);
}int get_rank_by_key(int x) {insert(x);int ans=tr[tr[root].ch[0]].size;remove(x);return ans;
}int get_key_by_rank(int k) {int u=root;while(true) {if(k<=tr[tr[u].ch[0]].size) u=tr[u].ch[0];else if(k<=tr[tr[u].ch[0]].size+tr[u].cnt) break;else k-=tr[tr[u].ch[0]].size+tr[u].cnt, u=tr[u].ch[1];}splay(u,0);return tr[u].v;
}int main() {insert(-inf);insert(inf);int n,T;cin>>n>>T;for(int i=1; i<=n; i++) {int x;cin>>x;insert(x);}int ans=0, last=0;while(T--) {int op,x;cin>>op>>x;x^=last;if(op==1) insert(x);else if(op==2) remove(x);else if(op==3) ans^=(last=get_rank_by_key(x));else if(op==4) ans^=(last=get_key_by_rank(x+1));else if(op==5) ans^=(last=tr[get_pre(x)].v);else ans^=(last=tr[get_suc(x)].v);}cout<<ans<<endl;return 0;
}/*
in:
6 7
1 1 4 5 1 4
2 1
1 9
4 1
5 8
3 13
6 7
1 4out:
6
*/



【参考文献】
https://www.luogu.com.cn/problem/P6136
https://blog.csdn.net/SunnyYuanJiawei/article/details/129836238
https://www.cnblogs.com/baijian0212/p/splay.html
https://www.acwing.com/solution/content/50494/
https://blog.csdn.net/hnjzsyjyj/article/details/134728992
https://blog.csdn.net/hnjzsyjyj/article/details/120380473
https://zhuanlan.zhihu.com/p/348797577







 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/7346.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

代码审计之浅谈RASP技术

前言&#xff1a; 想摆会烂&#xff0c;所以就落个笔吧。 其实本来是想写关于iast技术的&#xff0c;但是认真思考了下&#xff0c;感觉笔者自己本身也不太能讲清楚iast技术&#xff0c;怕误人子弟。 所以最后还是基于笔者的理解以及实际应用写一篇关于RASP技术的文章&#xf…

强化学习:时序差分法【Temporal Difference Methods】

强化学习笔记 主要基于b站西湖大学赵世钰老师的【强化学习的数学原理】课程&#xff0c;个人觉得赵老师的课件深入浅出&#xff0c;很适合入门. 第一章 强化学习基本概念 第二章 贝尔曼方程 第三章 贝尔曼最优方程 第四章 值迭代和策略迭代 第五章 强化学习实例分析:GridWorld…

软件游戏丢失XINPUT1_4.dll文件的多种解决方法分享

当玩家在尝试启动某款游戏时&#xff0c;遇到了系统提示“游戏找不到XINPUT1_4.dll”&#xff0c;这个错误通常发生在玩家尝试启动游戏时&#xff0c;游戏无法找到所需的XINPUT1_4.dll文件&#xff0c;呆滞无法正常启动运行。但是幸运的是&#xff0c;有一些简单的修复方法可以…

自制AI:Park_01修改bug

修改了一下不能存东西&#xff0c;不能打开东西的bug #include<bits/stdc.h> #include<windows.h> using namespace std; double mem10737418240; map<string,string> jishiben; string mulu"朴同学给你的一封信.memo\n"; int cntnote1; void sta…

软件测试与管理:黑盒测试-因果图法和场景法

知识思维导图&#xff1a; ​​​​​​​ 例题1&#xff1a;运用因果图法设计测试用例 有一个处理单价为5角钱的饮料的自动售货机软件测试用例的设计。其规格说明如下&#xff1a; 若投入5角钱或1元钱的硬币&#xff0c;按下〖橙汁〗或〖啤酒〗的按钮&#xff0c;则相应的饮料…

代码随想录算法训练营第四十六天|LeetCode139.完全平方数

LeetCode 139 完全平方数 题目链接&#xff1a;139. 单词拆分 - 力扣&#xff08;LeetCode&#xff09; 【解题思路】 1.确定dp数组以及下标含义 dp[j]的定义是&#xff1a; 字符串长度为i的话&#xff0c;dp[i]为true&#xff0c;表示可以拆分为一个或多个在字典中出现的单词…

[方法] Unity 实现仿《原神》第三人称跟随相机 v1.1

参考网址&#xff1a;【Unity中文课堂】RPG战斗系统Plus 在Unity游戏引擎中&#xff0c;实现类似《原神》的第三人称跟随相机并非易事&#xff0c;但幸运的是&#xff0c;Unity为我们提供了强大的工具集&#xff0c;其中Cinemachine插件便是实现这一目标的重要工具。Cinemachi…

4步快速配置Java和MySQL环境

每次入职一家新公司或者用一台其他的临时电脑或者新电脑时都要重新配置Java开发环境&#xff0c;很麻烦&#xff0c;因此我在这里记录一下快速配置环境的方式&#xff0c;四步搞定&#xff01;此处以win为操作系统进行讲解。 第一步&#xff1a;下载链接 下载链接&#xff1a…

二叉树1:二叉树的基本运算

1. (简答题) 编写一个程序&#xff0c;实现二叉树的基本运算&#xff0c;具体要求如下&#xff1a;&#xff08;指定示范实例1&#xff1a;P243图7.34。指定示范实例2&#xff1a;P201图7.13 &#xff09; 1&#xff0c;括号表示法输出该树。 2&#xff0c;输入一个结点的值&…

04.1.添加多个监控同步其他主机

添加多个监控&同步其他主机 1.首先在agent配置文件中存在Include的&#xff0c;也就是说明&#xff0c;可以配置多个监控项并且同步到其他主机上的进行使用&#xff1b; 2.主机之间互相推送配置文件即可&#xff1b; 开始测试 我这里实在agent节点上直接在路径/etc/zabbi…

Go实现树莓派控制舵机

公式说明 毫秒&#xff08;ms&#xff09;是时间的单位&#xff0c;赫兹&#xff08;Hz&#xff09;是频率的单位&#xff0c;而DutyMax通常是一个PWM&#xff08;脉冲宽度调制&#xff09;信号中表示最大占空比的值。以下是它们之间的关系和一些相关公式&#xff1a; 频率&…

Python内置函数min()详解

Python中的min()函数是一个内置函数&#xff0c;用于找出给定参数或可迭代对象中的最小值。 函数定义 min()函数可以有两种不同的使用方式&#xff1a; min(iterable, *[, defaultobj, keyfunc]) min(arg1, arg2, *args[, keyfunc])iterable&#xff1a;一个可迭代对象。def…

设计模式之建造者模式BuilderPattern(七)

一、建造者模式 建造者模式&#xff08;Builder Pattern&#xff09;使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式&#xff0c;它提供了一种创建对象的最佳方式。 二、代码实例 1、OrderItem类 Data&#xff1a;这是Lombok中提供的Ge…

【linux软件基础知识】-cdev_alloc

struct cdev *cdev_alloc(void) {struct cdev *p = kzalloc(sizeof(struct cdev), GFP_KERNEL);if <

并发编程陷阱:32位CPU下long写操作的线程安全漏洞

1. 现象描述 1.1 Bug问题简述 在多线程环境下操作共享数据时&#xff0c;往往面临各种并发问题。其中&#xff0c;一种常见的情况是&#xff0c;即使一段代码在单线程下执行没有问题&#xff0c;当它在多线程环境下执行时&#xff0c;却可能由于线程安全问题导致意想不到的Bu…

ADS过孔---过孔建模自动化

当前快速建模的方法有两类&#xff1a;一是脚本自动化&#xff0c;也就是今天要分享的方法&#xff0c;但该方法需要工程师有基本的脚本编辑能力&#xff0c;然后根据自己的需要去修改&#xff0c;难度较大一点点&#xff1b;二是参数化建模&#xff0c;也就是在GUI界面输入相应…

百度语音识别开发笔记

目录 简述 开发环境 1、按照官方文档步骤开通短语音识别-普通话 2、创建应用 3、下载SDK 4、SDK集成 5、相关接口简单说明 5.1权限和key 5.2初始化 5.3注册回调消息 5.4开始转换 5.5停止转换 6、问题 简述 最近想做一些语音识别的应用&#xff0c;对比了几个大厂…

华为手机连接电脑后电脑无反应、检测不到设备的解决方法

本文介绍华为手机与任意品牌电脑连接时&#xff0c;出现连接后电脑无反应、检测不到手机连接情况的解决方法。 最近&#xff0c;因为手机的存储空间愈发紧缺&#xff0c;所以希望在非华为电脑中&#xff0c;将华为手机内的照片、视频等大文件备份、整理一下。因此&#xff0c;需…

aardio爬虫) 实战篇:逆向有道翻译web接口

前言 之前的文章把js引擎(aardio封装库) 微软开源的js引擎(ChakraCore))写好了&#xff0c;这篇文章整点js代码来测一下bug。测试网站&#xff1a;https://fanyi.youdao.com/index.html#/ 逆向思路 逆向思路可以看有道翻译js逆向&#xff08;MD5加密&#xff0c;AES加密&…

cmake进阶:定义函数的内部变量

一. 简介 前一篇文章学习 cmake中的定义函数基本用法。文章如下&#xff1a; cmake进阶&#xff1a;定义函数的使用方法-CSDN博客 本文继续学习 cmake中的定义函数&#xff0c;主要学习函数的内部变量。 二. cmake进阶&#xff1a;定义函数的内部变量 上一篇文章说过&…