Kinetic Tournament Tree 不详细揭秘
Preface
此处的复杂度分析貌似挺不正论的,可以看一下论文。
丢掉了一些我做不动的题目,大伙就当看个题就好了。
Question
题目的形式是:
-
给定
l, r, v :\forall i \in [l, r] x_i = x_i + v (v > 0) 。 -
给定
l, r 求:\max^{r}_{i = l} f_i(x_i) 。
Theory
考虑对于每个节点维护一个目前最优的一次函数
更换的阈值即使两个一次函数的交点,注意 0 的除法。
然后对于每次更改我们自底向上维护,然后节点的
增加操作就直接如果
查询操作就是每次直接算就好了这个是简易的。
我们发现这个切换函数是一个爬树的过程,考虑与树高进行相关定义。
考虑定义势能函数
每次的增加,会给
所以结合深度,单次的势能增加为
那么
那么我们就可以用最多
Problem
CF1178G The Awesomest Vertex
树上做
P5693 EI 的第六分块
考虑最大子段和,是
这个可以看做一次函数的相加。然后时间复杂度的证明可以看 EI 自己的证明,理论大致和之前相同。
然后就是自然的合并,Implement 可以参考下面的。
P6792 [SNOI2020] 区间和
考虑使用 Seg-beats 的理论维护,这两套势能系统是分开算的,然后就是普通的区间加,区间最大子段和了。
但是实现细节 / 复杂度证明较为复杂,建议观看题解实现。
CF1868F LIS?
考虑一直对一个最长的最大子段和加,然后让他换下去。
不难做到
P9288 [ROI 2018] Innophone
先将贡献写成如下形式方便理清思路:
注意到
现在只需要有一个黑盒可以支持维护
这等价于维护若干个正比例函数
由于维护的斜率是单调的,只有可能由斜率大的的换上来,而且这个切换是不可逆的,所以修改并不会增加势能,复杂度
有双倍经验 CF436F Banners。
P8987 [北大集训 2021] 简单数据结构
注意到操作本质上是区间竖线移位,一个点在
注意到这个集合
证明:
- 加入这个集合的时候,集合中小于他的数全部都
\leq x - 这个时刻还没有加入这个集合的斜率小于他的数的值
\leq v ,所以满足截距小于他,所以未来的值只会比他大。
注意到这个性质后,直接线段树二分+推平即可解决问题。
问题是如果没有呢?
考虑使用 KTT,每次取出最大值即可,注意斜率是单调的。只会换大的数上来。同时维护一套区间加、区间和即可。
复杂度
P5073 [Ynoi2015] 世上最幸福的女孩
考虑按照
使用 KTT 维护即可过不了一点,理论复杂度正确!
但实际上做法应该是根据凸性,写闵可夫斯基和。
CF1830F The Third Grace
考虑记