题目大意
有一个长度为
n
的二元组数组,要求把它划分为若干段,不妨设划分出了
∑m−1i=0(maxrij=liaj)<=limitA
的情况下,最小化
maxm−1i=0(∑rij=libj)
其中 n<=20000
分析
答案显然可以二分,记为
limitB
,然而二分后直接乱塞显然是
0
分的。
考虑
fi=maxj<i,∑il=j+1bl<limitB(fj+maxik=j+1ak)
然而总时间复杂度
O(nlog2n)
无法接受。
考虑两个决策
k
和
然后不妨用线段树来维护决策 fj+maxik=j+1ak 的值。那么计算 fi 的时间复杂度降到了 O(logn) 。而维护这个值我们也是分开两部分维护,对于第一部分是简单的单点查询和维护最小值,第二部分是区间修改,再维护一个和的最小值,这道题就做完了。
由于我们每一次需要合并若干个组,然后将它们的
maxi
统一赋值。而
n
个组最多只需要合并成一个。那么合并以及对
时间复杂度 O(nlog2n) ,空间复杂度 O(n) 。
后记
这道题我在比赛时想的是用单调队列来维护决策。然而无法处理转移决策范围的问题。也就是说最优决策不一定能选到。其实这里用线段树就可以简单地回避了这个问题了,只是我没有去想如何很好的维护这个值,也有一点受之前做这类题目的影响吧。然而维护这个值并不是特别难的。
这道题算是对线段树使用的一个不错的技巧题。