给定一个数组的N个元素,计算该数组所有子数组的总和(min * max)。
例如 N = 5
数组:5 7 2 3 9
输出:346 (5 * 5 + 7 * 7 + 2 * 2 + 3 * 3 + 9 * 9 + 5 * 7 + 2 * 7 + 2 * 3 + 3 * 9 + 2 * 7 + 2 * 7 + 2 * 9 + 2 * 7 + 2 * 9 + 2 * 9)
我想不出比O(n ^ 2)更好的东西。编辑解决方案使用我无法理解的细分树。
答案 0 :(得分:1)
有关社论的提示(我不确定其详细信息):如果我们能够解决包括A[i]
和A[i+1]
在内的所有区间的问题,其中i
在A
时间内将O(n)
分成两半,然后我们可以使用分而治之,在O(n log n)
时间内解决整个问题,分别解决左右两边的问题,并加上重叠的时间间隔左右。
input:
5 7 2|3 9
i (divides input in half)
任务:在O(n)
中查找包含2和3的所有间隔的解决方案。
5 7 2 3 9
xxx
2 2 -> prefix min
2 2 2 <- prefix min
2 4 -> prefix sum min
6 4 2 <- prefix sum min
3 9 -> prefix max
7 7 3 <- prefix max
请注意,因为它们是单调递增的,所以可以将最大值视为扩展到下一个较高元素的相反前缀。例如,当标记当前最大值时,通过在任一方向上扩展指针,我们可以发现7扩展回9。然后,我们想将每个最大值乘以相关的最小前缀和。
当我们扩展标记当前最大值的指针并将最大值乘以前缀总和最小值(记住间隔必须同时跨越2和3)时的相关贡献:
3 * 2
7 * 2
7 * 2
9 * 6
这些原因包括以下时间间隔:
5 7 2 3 9
---
-----
-------
-----
-------
---------
3*2 + 7*2 + 7*2 + 9*2 + 9*2 + 9*2
现在分别解决左右的问题并添加。递归执行此操作是分而治之。