势能分析揭开一些算法的秘密

news/2025/9/20 21:39:54/文章来源:https://www.cnblogs.com/lalaouyehome/p/19102921

势能分析太厉害了!

势能分析主要是计算一些过程十分复杂的算法的时间复杂度。我们巧妙地借助物理中的势能解决问题,我们先定义一个状态的势能,将复杂度刻画为引起势能变化所做的功,而关于势能很多时候我们只关心始末状态,无序关心中间的具体做功情况,恰好能解决中间流程复杂的问题。

并且,势能分析主要用于分析一些均摊复杂度问题。我们可以把势能理解为“预付代价”,将过程前后联系起来。

具体的,我们将进行 \(n\) 次操作,定义 \(c_i\) 表示第 \(i\) 次操作所花费的时间,\(F(S)\) 表示状态 \(S\) 的势能,第 \(i\) 次操作结束时的状态为 \(S_i\),我们将第 \(i\) 次操作的摊还复杂度 \(\hat{c}_i\) 定义为:

\[\hat c_i=c_i+F(S_i)-F(S_{i-1}) \]

于是,\(n\) 次操作的摊还复杂度即为:

\[T=\sum_{i=1}^n\hat c_i=\sum_{i=1}^n c_i+F(S_n)-F(S_0) \]

而我们要求的是 \(\sum_{i=1}^n c_i\),我们可以通过计算 \(T\)\(F(S_n)-F(S_0)\) 的下界算出真实复杂度的上界。

刚开始学的人可能会有一些误区,做功显然不是只做正功,也有可能做负功。且我们主要是利用势能很好的性质,将操作与势能联系起来,通过若干数学技巧算出摊还复杂度,总之就是摊还复杂度和真实复杂度是不一样的,摊还复杂度还囊括了势能的影响。

对于一些很简单的问题我就不多讲了,我采取欧美打法,直接讲 Splay 和 LCT 复杂度的证明。

Splay 复杂度证明

我们定义 \(|x|\)\(x\) 的子树大小,对每个点构造势能函数 \(\phi(x)=\log|x|\),Splay \(S\) 的势能函数为 \(\phi(S)=\sum_{x\in S}\phi(x)\)

很明显我们只需要证明 splay 函数的复杂度是对的即可,其它操作只会增加常数。我们不难求出 \(\phi(S_n)-\phi(S_0)\) 的下界为 \(-n\log n\),接下来考虑计算摊还复杂度。

对于一次 rotate,我们花费的摊还复杂度显然是 \(\mathcal{O}(1)+\phi(x')-\phi(x)\)

对于 splay 的双旋,一字型旋转和之字形旋转,我贺了洛谷日报的图:

先考虑前者。我们的 \(\hat c_i=\mathcal{O}(1)+\Delta \phi(S)\)\(\Delta\phi (S)\) 的计算我们考虑用操作涉及涉及到的六个点刻画,我们不妨令操作 \(x,p,g\) 完之后代表的点变成 \(x',p',g'\)。那么

\[\Delta\phi(S)=\phi(x')+\phi(p')+\phi(g')-\phi(x)-\phi(p)-\phi(g) \]

注意到 \(\phi(x')=\phi(g)\)\(\phi(g')<\phi(x')\)\(\phi(p)>\phi(x)\),于是有

\[\Delta \phi(S)<\phi(x')-2\phi(x)+\phi(p') \]

我们尝试将 \(\phi(p')\) 消掉,考察 \(\phi(x)+\phi(p')-2\phi(x')\) 的性质。写出原式

\[\log|x|+\log|p'|-2\log |x'|=\log(\frac{|x||p'|}{|x'|^2}) \]

注意到 \(|x'|>|x|+|p'|\),于是不难放缩出

\[\log(\frac{|x||p'|}{|x'|^2})<\log(\frac{|x||p'|}{(|x|+|p'|)^2})<\log(\frac{|x||p'|}{2|x||p'|})=-1 \]

直接整体做减法可得

\[\Delta \phi(S)<\phi(x')-2\phi(x)+\phi(p')<\phi(x')-2\phi(x)+\phi(p')-1-(\phi(x)+\phi(p')-2\phi(x'))=3(\phi(x')-\phi(x))-1 \]

于是

\[\hat c_i=\mathcal{O}(1)+\Delta\phi(S)=3(\phi(x')-\phi(x)) \]

其中后面的 \(\mathcal{O}(1)\)\(-1\) 均摊掉了。

对于后者,我们采取类似的分析,\(\Delta\phi(S)=\phi(p')+\phi(g')-\phi(p)-\phi(x)<\phi(p')+\phi(g')-2\phi(x)\),考察 \(\phi(p')+\phi(g')-2\phi(x')\),发现仍然有小于 \(-1\),直接做减法然后算出

\[\hat c_i=\mathcal{O}(1)+\Delta\phi(S)=2(\phi(x')-\phi(x)) \]

我们知道,一次 splay 顶多一次单旋,于是一次操作摊还复杂度可以视作 \(\mathcal{O}(\log n)+\mathcal{O}(1)=\mathcal{O}(\log n)\)

看完了证明,我们将解决很多对于 splay 的一些一直不知道原因的问题:

  1. 为什么一字型旋转必须先旋父亲?因为不先旋父亲找不到类似 \(a+b<c,\log(\frac {a+b}{c^2})<-1\) 的性质,事实上它根本减少不了深度,我们一直加点就能卡掉。
  2. 为什么操作到哪就得 splay 到哪?这是个好问题。肤浅的人会认为 splay 保证了树高,这并没错,但是这不代表每一时刻都能控制在 \(\mathcal{O}(\log n)\) 内。注意了,我们复杂度证明算的可是摊还复杂度,跟实际复杂度已经是两码事了,总之,splay 是依赖于均摊的复杂算法,并不能肤浅地认为树高保持在 \(\mathcal{O}(\log n)\) 内,如果操作不 splay,我们相当于是独立于摊还证明之外了。
  3. 为什么不上手法的 treap 不能用在 LCT 中?这个待会讲 LCT 时再讲。

LCT 复杂度证明

类似的,LCT 时间复杂度本质上之来自于 access 操作。

这个我们分成两部分证明,一部分是 splay 的复杂度,一部分是在树上跳虚边的复杂度。

这边我只证明它的摊还复杂度,证完摊还再证实际复杂度是容易的。

Splay 中

我们定义 \(|x|\)\(x\) 在当前树中的子树大小,当前树定义为由所有虚边和 splay 的边组成的树。不妨还是令 \(\phi(x)=\log |x|\),状态 \(S\) 的势能 \(\phi(S)=\sum_{x\in S}\phi(x)\)

一次 access 操作中,不妨设它在树上跳虚边的时候一次访问了 \(x_1,x_2,\cdots,x_k\),而在之间的一棵 splay 中我们带来的摊还复杂度为 \(\mathcal{O}(1)+\Delta\phi(S)< \phi(x_i)-\phi(x_{i-1})\),小于的原因是 \(x_i\) 显然是 \(x_{i-1}\) 的 splay 上的根的父亲。于是加起来的摊还复杂度仍然能抵消,并满足 \(\mathcal{O}(\log n)\)

最后实际复杂度就是摊还加上变化上界,即 \(\mathcal{O}((n+m)\log n)\)

虚边上

考虑结合重链剖分进行分析。定义重虚边为既是重边又是虚边的数量,那么定义势能函数 \(\Phi\) 为所有重虚边的数量。

那么,我们每次最多走 \(\log\) 条轻虚边,也就是说至多带来 \(\log\) 条重虚边,均摊的很优雅。

而对于重虚边转轻虚边需要花费 \(\mathcal{O}(1)\) 的代价减小 \(1\) 的势能,对于做功常量,也就是轻虚边之间我们不用考虑,因为重链剖分的经典结论保证最多经过 \(\mathcal{O}(\log n)\) 条轻边。

于是复杂度直接就对了,因为我们总共最多就 \(\mathcal{O}(n+m\log n)\) 条轻虚边。

综上所述,LCT 复杂度为 \(\mathcal{O}((n+m)\log n)\)

通过我们的过程同样可以说明,LCT 也必须要操作到哪 access 到哪,并且,发现我们的过程利用了 splay 的摊还复杂度,而对于不上手法的 treap,复杂度可能会退化到两只老哥。

对于并查集的一些复杂度我先鸽了,有时间再写。

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

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

相关文章

企业省钱又安全的5款Linux发行版:从Ubuntu到Pop!_OS全面解析

本文详细分析了五款适合企业使用的Linux发行版,包括Ubuntu、Linux Mint、Debian、elementaryOS和Pop!_OS,重点探讨它们的硬件兼容性、安全特性、成本效益及部署优势,帮助企业实现安全与成本控制的双重目标。5款适用…

【深度学习新浪潮】数字孪生研发进展:从技术突破到代码实践 - 实践

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

how to count

Polygon 根据范围 dp 还是比较显然的。\(f_{i,j}\):将i边形分成j个多边形的方案数。 整体思考 一开始的方向是通过保证每种方案,对于每条分割线计算一次去重,对于每个状态的转移,枚举每条分割线,然后枚举两侧分割个…

第六章 数组

一维数组的使用具有相同类型的若干变量按有序形式组织起来,这些按序排列的同类数据元素称为数组 数组的元素是连续的(元素的内存地址连续) 同一个数组所有的成员都是相同类型 一维数组数据类型 数组名 [常量表达式] …

basic - graph theory

P2860 [USACO06JAN] Redundant Paths G 先转化为加尽量少的边使得图为边双。 注意到边双具有传递性,则先进行缩点。(此处注意tot=1和lst^1的实现细节) 则问题又转化为加尽可能少的边,使一个全是割点的图变成边双。 边…

详细介绍:阻塞 IO为什么叫BIO,非阻塞IO为什么叫NIO,异步IO为什么叫AIO

详细介绍:阻塞 IO为什么叫BIO,非阻塞IO为什么叫NIO,异步IO为什么叫AIOpre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family:…

Ubuntu系统使用gcc和Makefile编译C程序

一.用Ubuntu系统编写hello world程序并编译运行 1.用vim命令编写hello world程序代码

构造选记

CF1815B Sum Graph 考虑肯定要把图建成一个特殊形态,考虑链。指定x分别为\(n+1,n+2\)即可做到,这个时候链的实际形态已经确定下来(这里预处理出来链的实现没有想到)。有了链查询n-1次与\(p_1\)的距离,最长的肯定是…

0133_解释器模式(Interpreter)

解释器模式(Interpreter) 意图 给定一种语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。 UML 图优点易于扩展文法:由于使用类来表示语言的文法规则,可以通过继承来扩展文…

trick杂记 例题

会把一些不太有分类的trick放在这里,弄得好乱啊! 其实感觉大部分算不上trick,就是一些思考的方向)组合数学。一些决策对总贡献没有影响,可以先钦定它们,在该局面下考虑对总贡献有影响的决策。CF2092E She knows.…

代码随想录算法训练营第四天 | leetcode 24

两两交换链表中的节点 注意:交换两个节点的步骤,采用虚拟节点会更加方便,每次交换的步骤是相同的所以可以使用递归做出来(二刷再做吧),然后就是注意指针是否为空,普通做法时可以将保存交换节点的下一个接地点,…

网络流 最小割、费用流

网络流 最小割、费用流 割 网络流中的割被定义为一种点集的划分方式,源点 \(s\in S\) ,汇点 \(t\in T\) 割 \((S,T)\) 的容量为 \(c(S,T)\) 表示所有从 \(S\) 到 \(T\) 的边的容量之和 最小割问题就是求一个割 \((S,…

DP tricks

乱记随机做到的dptricks 交换状态与答案 适用场景:状态大但是答案小AT_dp_e Knapsack 2 CF176D Hyper String AT_agc033_d [AGC033D] Complexity用map存 写出明显存不了的状态的柿子之后 发现只有比较少的几个会有更新…

碎碎念(十七)

awa听风听雨,留云留意 还在怀念过去吗? 那个清晨一起抓住了温柔的风, 那个午后一起接住了淅沥的雨, 那个黄昏一起数清了着火的云, 那个夜晚一起点亮了暗淡的星。那么现在呢? 只能祈祷吹过相同的风, 只能独自撑起…

OpenCV的一些API的使用

本文章会陆续记录一些OpenCV的API方法

AdMergeX与小川科技最右App合作案例入选中国信通院“高质量数字化转型典型案例集” - 实践

AdMergeX与小川科技最右App合作案例入选中国信通院“高质量数字化转型典型案例集” - 实践2025-09-20 21:19 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !importan…

在 macOS 上准备 CentOS 7.5 离线迁移文件的完整指南

在 macOS 上准备 CentOS 7.5 离线迁移文件的完整指南本地使用的是 macOS,但目标机器是 CentOS 7.5,我们需要特别小心地准备兼容的安装包。以下是详细步骤: 准备工作:在 macOS 上设置环境 1. 创建工作目录 mkdir -p…

2971:抓住那头牛

题目 总时间限制: 2000ms 内存限制: 65536kB 描述 农夫知道一头牛的位置,想要抓住它。农夫和牛都位于数轴上,农夫起始位于点N(0<=N<=100000),牛位于点K(0<=K<=100000)。农夫有两种移动方式: 1、从X移动…

高效测试的第一步:5个用例设计基础思维模型

测试之路,思维先行。掌握这些基础思维模型,让你在测试领域走得更远更稳。欢迎分享你的测试设计经验和心得!在软件开发领域,测试是确保产品质量的关键环节。而对于测试工作来说,测试用例设计无疑是核心中的核心。一…

MFC Button 控件完全指南:从基础到进阶 - 指南

MFC Button 控件完全指南:从基础到进阶 - 指南pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", &…