势能分析法 学习笔记

势能分析法

概述

在进行部分操作时,我们操作的复杂度不一定符合题目要求(额外操作);但是如果 它的总复杂度 是符合要求的,那么这个操作也可以使用。

这种分析方法(思想)成为 势能分析法

分析

在进行势能分析时,关键是找到 总复杂度,其次是论证总复杂度是随着额外操作的进行而严格递减的。

为了找到总复杂度,我们可以尝试分析 每一部分代码的复杂度和调用次数

例子

典例1:线段树合并

inline int merge(int x,int y){
    if(!x || !y) return x+y;
    sum[x]+=sum[y];
    ls[x]=merge(ls[x],ls[y]);
    rs[x]=merge(rs[x],rs[y]);
    return x;
}

当 $ x \leq logN $ 且 $ y \leq N $ 时,且进行 \(N\) 次操作,总复杂度是\(O(nlogn)\)级别的。

首先除去递归部分之外,时间复杂度主要消耗在第一行和第二行。

我们逐个分析:

  • 对于第一行,只有在两个节点中的一个点是空节点时,我们才会运行,因此运行次数等于空儿子个数。有二叉树的性质,我们可以得知,这个数值等于 \(\text{叶子个数}+\text{只有一个儿子的节点数}\)\(x\)\(y\) 的约定可以得知,在每一次操作中,这部分的时间复杂度不超过 \(O(logn)\)

  • 对于第二行,每一次运行都会时总节点个数减一,而总节点个数是一定的,因此这部分时间复杂度不超过 \(O(nlogn)\)

综上这部分代码的总复杂度是 \(O(n*logn+nlogn)=O(nlogn)\) 的。

总结

只要找到时间复杂度开销大的地方,进行分析,找到总量,明确递减,就说明算法可行。

posted @ 2025-07-08 21:25  XiaoZi_qwq  阅读(10)  评论(0)    收藏  举报