【笔记】传统势能线段树
1 引入
传统线段树能够通过打标记实现区间修改的条件有两个:
- 能够快速处理标记对区间询问结果的影响;
- 能够快速实现标记的合并。
有的区间修改不满足上面两个条件。
但存在一些奇妙的性质,使得序列每个元素被修改的次数有一个上限。
如果我们保证每暴力
具体到实现,可以考虑在线段树每个节点上记录一个东西(需要依题而定),用来表达对应区间内是否每个元素都达到修改次数上限。区间修改时暴力递归到叶子节点,如果途中遇到一个节点,这个节点的对应区间内每个元素都达到修改次数上限则在这个节点直接 return 掉。
2 关于势能在时间复杂度计算上的应用
首先定义一个势能函数初始值就是每个元素至多被修改的次数之和。
每次操作如果势能都是不增的,那么整体的复杂度就不会超过初始势能函数的值。
3 应用
p.s. 下面都是修改操作,查询操作应该是传统线段树能做的她都能做(?
3.1 区间取模
显然每次取模每次都让原数至少减少一半,修改上限就是
具体到实现,我们维护每个区间的最大值,如果区间最大小于模数,那么就可以不用递归下去了。
3.2 区间开方
3.2.1 Solution1 维护是不是全
首先,对于任意数开方,可以在至多
why? 其实也很好理解,因为开方一次相当于
与 3.1 类似,还是维护区间最大值就行了。
3.2.2 Solution2 维护是不是全相等
其实这道题还有一种维护方式。
直接维护区间最大值、最小值,以此来看区间是不是全部相同,如果是就直接打区间覆盖的标记。
3.2.3 区间开方,区间加法
现在我们先用势能去理解一下上面两种维护方式。
对于第一个,对于每个节点其势能函数应该是该区间还不是
对于第二个,对于每个节点其势能函数应该是该区间不同的元素个数。
现在加上区间加之后,我们发现第一个势能函数会增加了,时间复杂度假了,但是第二个并不会!所以说,如果有区间加就只能用第二种维护方式。
但是还没完,对于这样的数据:3434,开方为 1212,再加 2 为 3434,这样就会循环。
解决办法是直接特判一下这种情况。
对于
对于
3.3 区间除法
与取模类似每次都让原数至少减少一半,修改上限同样也是
注意,这里除法的结果是要数学上的向下取整的话,如果是正数最后会停在
如果是用 3.2.1 的维护方式,需要分别维护区间是不是全
下面还是考虑 3.2.2。
还是特判
对于
对于
4 总结
对于常见的数学运算(比如取模就不算),一般都可以考虑 3.2.2 维护方式,即:
考虑维护
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!