【神奇分治】一道分治题

给一个长度为n的序列,求所有区间最大值乘以最小值的和。N<=500000.

网上找不到题,,,想验证代码写个暴力倒是挺好写的

我们考虑这个序列的所有的数据都是随机的话,那么我们如果每次找一个最大值,以这个最大值作为分隔,可以保证在这个最大值附近的最小值
是连续的,那么如果我们用一个单调栈维护一下的话,就一定在一段连续的区间内的min值相同,我们就可以算出来。其实由于我们每次从大到小找
最大值,那么我们就去除了一个考虑条件,只用考虑区间最小值,然后就可以搞了。
网上好多用的都是这个,,由于随机,期望平均时间复杂度是nlogn,但事实上我们将最大值搞得很偏的话会递归很多层,那么这就不够好,会卡成n^2

就考虑严格logn的从中间剖开分治

我们分治,每次只用考虑跨过mid的区间[L,R]
我们从mid向前O(n)扫得到一个后缀最大最小值,从mid向后O(n)扫得到一个前缀最大最小值
我们枚举,L从mid开始往l枚举。我们设定两个类指针p,q

p指的是,从[L,p)其最大值都等于maxL
q值得是,从[L,q)其最小值都等于minL
那么对于mid->min(p,q)以这一段作为右端点L作为左端点的和为max[L]min[L]区间长
对于p,q之间我们预先处理max[L],min[L]的区间和(前缀最大值或前缀最小值的区间和)
p,q之间这一段就可以搞出来了
对于p,q之后这一段就不由L决定了,完全由之后的max[i]min[i]决定。我们完全可以预处理区间max[i]min[i]的和,这样就搞出来了。

我们画图考虑就是如下了。orz orz

9957068470f194770845ab92fd04c4d4.png

代码自己写啊,hhhhh(后期补上)

posted @ 2018-07-29 20:44  Newuser233  阅读(4)  评论(0)    收藏  举报