波长 题解
待补
很早以前模拟赛的题了,感觉挺有意思,写一下。
有点反人类。
首先你肯定会二分答案 \(w\),考虑 check,先对 \(a\) 前缀和一下,于是变成了后缀减 \(1\),使其满足任意 \(j > i, a_j - a_i < w\)。
考虑扫这个,维护一个 \(lim\),每次遇到 \(a_i\) 若 \(a_i > lim\) 就做后缀减直到 \(a_i = lim\),然后更新 \(lim \gets^{\min} a_i + w\)。
发现后缀减纯粹的玩原神,不如让 \(lim\) 加,容易发现其是等价的。
正解一定是要快速统一维护 \(L(x)\) 表示 \(w = x\) 时的 \(lim\) 和 \(S(x)\) 表示 \(w = x\) 时操作次数和的,考虑如何做,将其操作依次写出来:
考虑到 \(L(x)\) 的变化,每次和一条水平线取 \(\max\) 和和一条 \(k = 1\) 的直线取 \(\min\),容易发现其具有单调性,画画图容易发现其每次一定是将一段前缀推平,直接上栈都能维护了。
对于 \(S\) 不太好对 \(L\) 整体做,考虑对每段分别做,但是发现有贡献的段必然满足 \(L(x) < a_i\),但是 \(L(x) < a_i\) 在下一步就会被立刻推平,所以复杂度均摊也是对的。
说这题反人类的原因是这个题第一眼看上去有个类似贪心的东西明显比二分答案有前途,但实际上那个贪心做法并没有比较正常的正解写法。
题解中说的差分约束做法我实在是看不懂了,有人讲解一下吗?
待补