数组 – 优化在子数组上执行的查询

我最近在谷歌接受了采访.由于这个问题,我的过程在2轮之后没有向前推进.

Suppose you are given an array of numbers. You can be given queries
to:

  1. Find the sum of the values between indexes i and j.
  2. Update value at index i to a new given value.
  3. Find the maximum of the values between indexes i and j.
  4. Check whether the subarray between indexes i and j, both inclusive, is in ascending or descending order.

我给了他一个解决方案,但它是检查索引i和j之间的子阵列.他让我对它进行优化.我想使用哈希表,以便如果起始索引相同且结束索引大于上一个索引,我们存储最大值以及它是以升序还是降序并仅检查剩余的子阵列.但是,这并没有根据需要对其进行优化.
我很想知道如何优化解决方案以使其可以接受.

约束:

一切从[1,10 ^ 5]

谢谢 :)

最佳答案 在最坏的情况下,所有这些查询都可以在每个查询的O(log N)时间内回答(预处理的时间为O(N)).您可以构建一个段树,并为每个节点维护总和,最大值和两个布尔标志(它们指示对应于此节点的范围是否按升序/降序排序).所有这些值都可以有效地重新计算以用于更新查询,因为只有O(log N)个节点可以更改(它们位于从根到与更改元素对应的叶子的路径上).所有其他范围查询(sum,max,sorted or not)被分解为O(log N)节点(由于段树的属性),并且很容易将O(1)中两个节点的值组合在一起(例如,对于sum,组合2个节点的结果只是这些节点的值的总和.

这是一些伪代码.它显示了应该在节点中存储哪些数据以及如何组合2个节点的值:

class Node {
    bool is_ascending
    bool is_descending
    int sum
    int max
    int leftPos
    int rightPos
}

Node merge(Node left, Node right) {
    res = Node()
    res.leftPos = left.leftPos
    res.rightPos = right.rightPos
    res.sum = left.sum + right.sum
    res.max = max(left.max, right.max)
    res.is_ascending = left.is_ascending and right.is_ascending 
        and array[left.rightPos] < array[right.leftPos]
    res.is_descending = left.is_descending and right.is_descending 
        and array[left.rightPos] > array[right.leftPos]
    return res
 }
点赞