「hyOI2020」henry_y 的数列题解及一种分块优化最小值左移的想法
摘要
本文从经典的区间加一次系数非负的一次函数及维护区间最值问题开始,探究一种利用分块优化最小值下标左移的思路而不使用凸壳算法
记录符号
区间加 k \geq 0 的一次函数及维护区间最值问题
维护一个长度为
1 l r k b:\forall l \leq i \leq r, i \in \mathbb{N} ,令A_i \leftarrow A_i + ki + b ;2 l r:输出\min_{l \leq i \leq r} \{A_i\} 的值。
保证
解法 1:分块维护二维凸壳
这是本题的经典解法。
对序列分块,块大小为
相当于求块内
注意到
-
- 函数斜率
i 递增。
所以重构块和维护询问时都可以使用单调队列,避免二分增加
时间复杂度:
解法 2:分块优化最小值左移
同样考虑分块,块大小为
- 块中最小值所在的下标(如果有多个最小值,取下标最小的)
\text{minpos} ; - 令整个块最值改变所需的最少的
\sum k 值\text{limk} 。
考虑求解
所以
对每个块记录两个懒惰标记(Lazy tag)
时间复杂度:
复杂度证明
设块的势能为它在仅受整体影响(即不出现边角情况,不出现局部影响)下能被重构的最多次数。
首先,单个块的势能不超过
其次,若块内
考虑修改操作的影响。
- 对修改区间外:无影响。
- 对处于修改边界上的元素:由于修改边界最多只有
O(1) 个,因此势能增加不超过O(1) 。 - 对处于修改区间内的元素:注意到
A_{j - 1} 的增加量不大于A_j 的增加量,因此A_{j - 1} < A_j 的相对大小不变,而A_{j - 1} \geq A_j 可能在修改后变为A_{j - 1}' < A_j' 。此时满足条件的j 的数量不增多,势能不增大。虽然这可能引起块的重构,但重构最多仅O(1) 次,而如果重构则势能减少至少O(1) ,所以对总复杂度没有影响。
可见单次修改操作均摊增加势能为
考虑询问操作的影响。询问操作不改变元素的实际值,只下放标记,因此势能不变。
所以,所有操作增加的势能不超过
综上所述,可能的总重构次数,即总势能不超过
区间加一次函数及维护区间最值问题
维护一个长度为
1 l r k b:\forall l \leq i \leq r, i \in \mathbb{N} ,令A_i \leftarrow A_i + ki + b ;2 l r:输出\min_{l \leq i \leq r} \{A_i\} 的值。
解法:分块维护二维凸壳
采用和区间加
时间复杂度:
伪解法:分块优化最小值左移
可以使用类似的思路吗?
类似地,我们维护令整个块最小值改变所需绝对值最小的
不幸地,这一方法最坏复杂度为
- 初始时,令
A_i = n - i 。此时\{A_n\} 单调递减。 - 令全局增加
2i 。此时\{A_n\} 变为单调递增,所有块被重构,复杂度为O(\sqrt n) = O(\sqrt n) = O(n) 。 - 为了防止不查询就不重构块的做法,查询全局最小值。
- 令全局减少
2i 。此时\{A_n\} 又变为单调递减,所有块又被重构,复杂度为O(\sqrt n) = O(\sqrt n) = O(n) 。此时\{A_n\} 回到初始状态。 - 转到第 2 步,重复。
以这样的方式,此算法会在
特别地,该算法在部分随机数据下表现较良好(可见 Moonoshawott 在洛谷 P4192 旅行规划 的提交记录)。但仍然要指出的是,选手应尽可能使用正确的算法,否则可能会因随机数据的常数或构造数据方式的不同而表现不优。
「hyOI2020」henry_y 的数列(区间加 a, b \geq 0 的二次函数及维护区间最值问题)
维护一个长度为
1 l r a b c:\forall l \leq i \leq r, i \in \mathbb{N} ,令A_i \leftarrow A_i + ai^2 + bi + c ;2 l r:输出\min_{l \leq i \leq r} \{A_i\} 的值。
保证
解法 1(?):分块维护三维凸壳
采用和区间加
由于笔者学识浅薄,此处不对该解法的正确与否妄下断语。如果有选手可以以优秀的复杂度实现这个算法,可以在题目讨论区里留言。
解法 2:分块维护二维凸壳优化最小值左移
回顾一下我们刚才的所有证明。不难发现,维护这个只需要满足以下条件:
- 可以在
O(\sqrt n) 时间内完成对一个块的重构 - 可以在均摊
O(1) 时间内判断一个块的最小值的位置是否必须发生改变 - 可以在
O(1) 时间内维护修改标记并在重构时下放 - 对于修改区间内的相邻元素,有
\Delta A_i \leq \Delta A_{i + 1} (即A_i 增加的值不大于A_{i + 1} 增加的值)
不难发现区间加
设标记
把不等式的右半部视作关于
若条件满足,则重构此块。至于复杂度:
综上,我们可以用分块维护上凸壳的方法解决这个问题。
时间复杂度:
伪解法:分块钦定二维凸壳优化最小值左移
此解法由 @hjw 提出,在此感谢 hjw 的协助验题、提出算法和提供构造数据的方式。
同样分块,并把每个元素视为二维平面上的点
对于每次询问,设
尽管这个算法看起来不太正确,但它仍通过了几乎所有的随机数据和部分构造数据。笔者试着思考了三天,也没能找出卡掉此算法的构造方式。
要证明这个算法的正确性,只需要证明:
- 不在下凸壳上的点不会成为唯一的最小值(优越性)。
- 设
i < j < k 在下凸壳上。对于任意时刻,若a_i' < a_j' ,那么一定有a_j' < a_k' (传递性)。
传递性是正确的,可以通过简单的反证法证明。因此,若最小值在下凸壳上,那么这个算法一定能得出正确结果。几乎所有的随机数据都满足最小值在下凸壳上,因此得出的结果是正确的。
然而优越性是错误的,可以构造出反例。@hjw 给出了一种构造反例的方式:
- 决定
1 \leq i < j < k ,其中j - i \leq k - j 。 - 决定
\alpha, C ,使得区间加上\alpha i^2 + C 。 - 计算
A_i = \alpha(k^2 - i^2) + C, A_j = \alpha(k^2 - j^2) - 1 + C, A_k = C 。
此时
利用此构造方法即可构造出卡掉此算法的数据。
时间复杂度:
后记
为了叙述简洁易懂,本文中仅描述了维护最小值的方法。维护最大值的方法是类似的,且可以以相同的复杂度同时维护最大值与最小值。
本文描述的分块优化最小值左移的思路,对于区间加非常数项系数均非负的