第六分块时间轴分块题解
因为大家写的都是序列分块基数排序套闵可夫斯基和,于是我来写一个既不用序列分块也不用闵可夫的对时间轴分块加普通凸包的版本。
时间轴分块是好文明。
弱化版
首先,先考虑一个全局修,全局查最大前缀和、最小前缀和,以及一个全局最大子段和的结构怎么做?
先将整个序列做一个前缀和。考虑第
这是一个关于
我们发现这两个东西可以看成多个半平面的交,且半平面是递增的。于是我们考虑每个点维护由这多个直线分别构成的上凸壳和下凸壳。
下凸壳同理。
然后考虑全局最大子段和。
我们对每个点维护
这个可以在
于是我们就可以维护一个斜率优化了。具体的,我们从右往左扫描过去,每次往当前的凸包里加一个数的同时在当前凸包里做一下。
容易发现答案是单调的,因此我们可以直接在凸包上暴力做,时间复杂度
然后我们考虑如何根据这个计算最大子段和。容易想到的是,最大子段一定是极大子段:若有一个子段
于是我们就可以考虑到,极大子段中一定不存在负数前缀和与负数后缀和。即,一个极大子段内的所有数,都满足以其为左端点/右端点的子段中至少有一个比他大。
然后我们就想到维护按照左右边界维护极大子段,然后随着
强化版
我们发现这次是区间修。
于是我们每
这样子,序列就被这些询问分成了
于是我们就直接线性地求出每个区间的最大前缀和,最小前缀和,最大子段和的凸包,然后对每个询问通过全局的排序(这里可以直接每组排序一次或者整体排序,因此不需要基数排序了)处理掉的情况,最终就直接普通的递推合并即可。
最终复杂度
代码咕了。