Splay和LCT的复杂度分析

Stella981
• 阅读 703

$Splay$的复杂度分析

不论插入,删除还是访问,我们可以发现它们的复杂度都和$splay$操作的复杂度同阶,只是一点常数的区别

我们不妨假设有$n$个点的$splay$,进行了$m$次$splay$操作


采用势能分析

我们记$w(x) = \left \lceil \log_2 (size(x)) \right \rceil$,注意以$2$为底和上取整

我们定义势能函数为$\varphi = \sum w(x)$

(记第$i$次操作操作完之后,势能为$\varphi(i)$)

只需要估计出$\varphi(m) - \varphi(m - 1) + \varphi(m - 1) - \varphi(m - 2) ... + \varphi(1) - \varphi(0) + \varphi(0)$的大小即可

(即初始势能和每次的势能变化量的和)

显然,$\varphi(0) \leqslant n \log n$


$splay$操作的具体定义为:

如果父节点是根,那么旋转一次

如果父节点和爷节点所处子树方向一致,那么先旋转父亲再旋转自己

否则,旋转两次自己

实际上可以归结于$zig$,$zag$,$zig-zig$,$zag-zag$,$zig-zag$,$zag-zig$操作

由于$zig$和$zag$是对称的操作

因此,只需要对$zig$,$zig-zig$,$zig-zag$操作分析复杂度即可


$zig$操作

Splay和LCT的复杂度分析

势能的变化量为$1 + w'(x) + w'(fa) - w(x) - w(fa) \leq 1 + w'(fa) - w(x) \leq 1 + w'(x) - w(x)$


$zig-zig$操作

Splay和LCT的复杂度分析

势能变化量为$1 + w'(x) + w'(fa) + w'(g) - w(x) - w(fa) - w(g)$(缩小了常数的影响,但不能无视)

$\leq 1 + w'(fa) + w'(g) - w(x) - w(fa) \leq 1 + w'(x) + w'(g) - 2w(x)$

这是神仙复杂度证明中非常神奇的地方,通过一些有趣的性质,让常数项的代价合并到了势能的变化中

我们不妨设$a = w'(g), b = w(x)$,那么注意到$w'(x) = a + b + 1$

由于$2w'(x) - w'(g) - w(x) = \left \lceil \log_2 (a + b + 1) \right \rceil - \left \lceil \log_2 a \right \rceil + \left \lceil \log_2 a + b + 1 \right \rceil - \left \lceil \log_2 b \right \rceil $

注意到$a, b$在上式中是对称的,不妨设$a \geq b$

$\geq \left \lceil \log_2 (a + b + 1) \right \rceil - \left \lceil \log_2 b \right \rceil \geq \left \lceil \log_2 (2b + 1) \right \rceil - \left \lceil \log_2 b \right \rceil \geq \left \lceil \log_2 b \right \rceil + 1 - \left \lceil \log_2 b \right \rceil \geq 1$

因此有$1 \leq 2w'(x) - w'(g) - w(x)$,我们将$1 + w'(x) + w'(g) - 2w(x)$中的$1$放缩,可以得到

$\leq 3(w'(x) - w(x))$


$zig-zag$操作

Splay和LCT的复杂度分析

势能变化量为$1 + w'(x) + w'(fa) + w'(g) - w(x) - w(fa) - w(g) \leq 1 + w'(fa) + w'(g) - w(x) - w(fa) \leq 1 + w'(g) + w'(fa) - 2w(x)$

由上文的结论,我们知道这里可以把$1$放缩成$1 \leq 2w'(x) - w'(g) - w'(fa)$

因此$\leq 2(w'(x) - w(x))$


把以上三种操作的势能全部放缩为$\leq 3(w'(x) - w(x))$

不妨假设$splay$一次,依次访问了点$x_1, x_2 ... x_n$,最后$x_1$会成为新的根

那么,最后的势能实际上是$3(w'(x_1) - w(x_1) + w''(x_1) - w'(x_1) + .... + w(n) - w^{'''.....}(x_1)) + 1 = 3 * (w(n) - w(x_1)) + 1\leq log_2 n$

因此,$\varphi(m) - \varphi(m - 1) + \varphi(m - 1) - \varphi(m - 2) ... + \varphi(1) - \varphi(0) + \varphi(0) = n \log n + m \log n$

即$n$个点的$splay$,做$m$次$splay$操作,复杂度为$O(n \log n + m \log n)$


$LCT$的复杂度分析

不咕了....

$LCT$的所有操作可以看做只有$access$操作,其他都是常数

那么$access$操作一共有两部分

  • 在$splay$中走的复杂度

  • 访问虚边的复杂度


首先是在$splay$中走的复杂度

定义$w(x) = \left \lceil \log_2 (size(x)) \right \rceil$,$size(x)$指$x$的所有虚边和实边的子树大小的和

我们定义势能函数为$\varphi = \sum w(x)$

不妨设它依次访问了$x_1, x_2 ..., x_p$

那么,类似上文$splay$的复杂度分析,我们可以得到总的一次势能变化量为$-w(x_1) +w(x_2) - w(x_2) + w(x_3) ... +w(x_p) + 1\leq w(x_p) + 1 = O(\log n)$

这也就是$splay$的$finger-search$的性质

初始势能为$n \log n$,因此这一部分的复杂度为$O(n\log n + m \log n)$


访问虚边的复杂度

我们定义势能函数$\phi$,为所有重虚边(儿子的子树大小大于等于自己的二分之一的虚边)的数量

那么,每次访问至多走$\log$条轻虚边,也就至多带来$\log$条重虚边,也就是以$O(\log)$的代价增加$\log$的势能

而每次访问一条重虚边就需要付出$O(1)$的代价来减小$1$的势能,并且访问完重虚边之后,不会有新的重虚边产生

因此,最终的复杂度是初始势能和势能变化量(实际操作的代价和势能变化量相同)的和,也就是$O(n + m \log n)$


因此,$LCT$的复杂度为$O(n \log n + m \log n)$

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
SpringBoot整合Redis乱码原因及解决方案
问题描述:springboot使用springdataredis存储数据时乱码rediskey/value出现\\xAC\\xED\\x00\\x05t\\x00\\x05问题分析:查看RedisTemplate类!(https://oscimg.oschina.net/oscnet/0a85565fa
Easter79 Easter79
3年前
SpringBoot整合Redis乱码原因及解决方案
问题描述:springboot使用springdataredis存储数据时乱码rediskey/value出现\\xAC\\xED\\x00\\x05t\\x00\\x05问题分析:查看RedisTemplate类!(https://oscimg.oschina.net/oscnet/0a85565fa
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
9个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这