分块 + 斜率优化.
选择的 $a$ 一定是某个出现过的 $x$ ,或者 $a$ 大于所有的 $x$ .
否则将 $a$ 增大到下个出现过的 $x$ ,答案不会变劣, $b$ 的选择同理.
于是可以从小到大枚举 $a$ ,只需要考虑 $b$ 的选择对 $x<a$ 的点贡献的影响.
将所有 $x<a$ 的点按照 $y$ 从小到大排序.
若共有 $cnt$ 个点的 $x<a$ ,那么选择第 $i$ 个点的 $y$ 作为 $b$ ,带来的贡献是 $v_i=(cnt-i+1)\cdot y_i$ .
随着 $a$ 的增大, $x<a$ 的点会不断增多,每加入一个新点,它后面的点 $v_i$ 不变,前面的点的 $v_i$ 会加上 $y_i$ .
如果直接用平衡树打标记,修改后没法得到区间内新的 $\max v_i$ ,考虑分块来处理.
若某一块整体被加了 $tag$ 次,那么块内真正的贡献为 $v_i’=tag\cdot y_i+v_i$ ,变形得到 $v_i=-tag\cdot y_i+v_i’$ .
即用一条斜率为 $-tag$ 的直线去截块内所有点,要最大化截距,于是可以维护出块内所有点的上凸壳.
斜率只会变小,被截到的点只会往右侧移动,那么不用在凸壳上二分,记录一下当前被截到的是哪个点即可.
先算出所有点都被插入时,每个点分别在哪一块,插入时直接插到那一块中即可.
插入点时,重构一下插入的那一块的上凸壳,修改前面所有非空块的 $tag$ ,并重新计算它们的贡献.
时间复杂度 $O(n\log n+n\sqrt n)$ .
1 | //%std |