计算数组所有子数组中(min * max)的总和

时间:2020-05-10 04:29:56

标签: arrays algorithm data-structures segment-tree

给定一个数组的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)

here is the complete question

我想不出比O(n ^ 2)更好的东西。编辑解决方案使用我无法理解的细分树。

1 个答案:

答案 0 :(得分:1)

有关社论的提示(我不确定其详细信息):如果我们能够解决包括A[i]A[i+1]在内的所有区间的问题,其中iA时间内将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

现在分别解决左右的问题并添加。递归执行此操作是分而治之。