\(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\)操作

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


\(zig-zig\)操作

势能变化量为\(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\)操作

势能变化量为\(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)\)

Splay和LCT的复杂度分析的更多相关文章

  1. 相似度分析,循环读入文件(加入了HanLP,算法第四版的库)

    相似度分析的,其中的分词可以采用HanLP即可: http://www.open-open.com/lib/view/open1421978002609.htm /****************** ...

  2. 文本离散表示(三):TF-IDF结合n-gram进行关键词提取和文本相似度分析

    这是文本离散表示的第二篇实战文章,要做的是运用TF-IDF算法结合n-gram,求几篇文档的TF-IDF矩阵,然后提取出各篇文档的关键词,并计算各篇文档之间的余弦距离,分析其相似度. TF-IDF与n ...

  3. 八大排序算法详解(动图演示 思路分析 实例代码java 复杂度分析 适用场景)

    一.分类 1.内部排序和外部排序 内部排序:待排序记录存放在计算机随机存储器中(说简单点,就是内存)进行的排序过程. 外部排序:待排序记录的数量很大,以致于内存不能一次容纳全部记录,所以在排序过程中需 ...

  4. 八大排序算法——堆排序(动图演示 思路分析 实例代码java 复杂度分析)

    一.动图演示 二.思路分析 先来了解下堆的相关概念:堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆:或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆.如 ...

  5. 八大排序算法——希尔(shell)排序(动图演示 思路分析 实例代码java 复杂度分析)

    一.动图演示 二.思路分析 希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序:随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止. 简单插 ...

  6. 八大排序算法——基数排序(动图演示 思路分析 实例代码java 复杂度分析)

    一.动图演 二.思路分析 基数排序第i趟将待排数组里的每个数的i位数放到tempj(j=1-10)队列中,然后再从这十个队列中取出数据,重新放到原数组里,直到i大于待排数的最大位数. 1.数组里的数最 ...

  7. 八大排序算法——归并排序(动图演示 思路分析 实例代码java 复杂度分析)

    一.动图演示 二.思路分析 归并排序就是递归得将原始数组递归对半分隔,直到不能再分(只剩下一个元素)后,开始从最小的数组向上归并排序 1.  向上归并排序的时候,需要一个暂存数组用来排序, 2.  将 ...

  8. 八大排序算法——快速排序(动图演示 思路分析 实例代码Java 复杂度分析)

    一.动图演示 二.思路分析 快速排序的思想就是,选一个数作为基数(这里我选的是第一个数),大于这个基数的放到右边,小于这个基数的放到左边,等于这个基数的数可以放到左边或右边,看自己习惯,这里我是放到了 ...

  9. 6.3 基于二分搜索树、链表的实现的集合Set复杂度分析

    两种集合类的复杂度分析 在[6.1]节与[6.2]节中分别以二分搜索树和链表作为底层实现了集合Set,在本节就两种集合类的复杂度分析进行分析:测试内容:6.1节与6.2节中使用的书籍.测试方法:测试两 ...

随机推荐

  1. vue组件间通信

    组件间通信(父子,兄弟) 相关链接\组件通信http://www.cnblogs.com/xulei1992/p/6121974.html 学习链接Vue.js--60分钟快速入门http://www ...

  2. 【多视图几何】TUM 课程 第4章 同名点匹配

    课程的 YouTube 地址为:https://www.youtube.com/playlist?list=PLTBdjV_4f-EJn6udZ34tht9EVIW7lbeo4 .视频评论区可以找到课 ...

  3. 如何提高单片机Flash的擦写次数

    所谓提高flash的擦写次数,并不是真正的提高flash擦写次数,而是通过以"空间换时间"概念,在软件上实现“操作的次数大于其寿命”.详见链接: http://bbs.eeworl ...

  4. java 一个函数如何返回多个值

    在开发过程中,经常会有这种情况,就是一个函数需要返回多个值,这是一个问题!! 网上这个问题的解决方法: 1.使用map返回值:这个方法问题是,你并不知道如何返回值的key是什么,只能通过doc或者通过 ...

  5. Eclipse中各种编码格式及设置

    操作系统:Windows 10(家庭中文版) Eclipse版本:Version: Oxygen.1a Release (4.7.1a) 刚看到一篇文章,里面介绍说Ascii.Unicode是编码,而 ...

  6. Shell脚本系列教程二: 开始Shell编程

    Shell脚本系列教程二: 开始Shell编程 2.1 如何写shell script? (1) 最常用的是使用vi或者mcedit来编写shell脚本, 但是你也可以使用任何你喜欢的编辑器; (2) ...

  7. centos7 安装java和tomcat9

    centos7 安装java 下载好java安装包后,首先是解压,然后配置环境变量. 在usr下新建Java文件夹,把java解压到Java文件夹中 新建文件夹 # mkdir /usr/Java 键 ...

  8. No.6 selenium学习之路之下拉框Select

    HTML中,标签显示为select,有option下拉属性的为Select弹框 1.Xpath定位 Xpath语法,顺序是从1开始,编程语言中是0开始

  9. Effective STL 学习笔记14: Use reserve to avoid unnecessary reallocations.

    vector 和 string 容器在动态插入一个新的对象时,如果容器内空间不够,该容器会: 重新分配空间 通常的做法是分配当前 Capacity 大小两倍的空间. 将旧空间中的所有元素拷贝进新的空间 ...

  10. ES按资源类型统计个数

    一.目标:统计各类型资源的个数,输出详细报表 http://10.10.6.225:9200/dsideal_db/t_resource_info/ _mapping {  "propert ...