从序列中减去一个数字后,剩余数字中有多少是正数?

时间:2013-09-08 19:12:38

标签: c++ math graph-algorithm

我有一个长度 N 的数字序列。 我将不得不对此数字序列执行 Q 操作。

在每个操作中,我将给出三个整数 P,Q,V ,其中P≤Q≤N,并将从每个减去 V iᵗʰ整数,其中P≤i≤Q

每次操作后,我将再给出两个整数 X,Y X≤Y≤N。我将不得不回答XᵗʰYᵗʰ(包括)整数之间的整数是多少。

Q 将在 10 5 附近。我将不得不在大约1/2秒内完成所有操作并回答相应的查询。

我应该使用什么算法/数据结构?程序将是什么?

注意:我对Segment Trees或Binary Indexed Trees有很好的了解。如果您的解决方案涉及这些数据结构,那将非常棒。

2 个答案:

答案 0 :(得分:7)

数据结构

对数据结构使用具有延迟传播的分段树。

在每个节点商店中:

  1. 所有子节点中的正值数
  2. 所有子节点的最小正值(即对于值为-1,3,5,-10的子节点,最小正值为3.我们忽略-1和-10,因为它们不是正数。)
  3. 要从此节点中减去的待定值(初始化为0)
  4. 更新

    更新范围的程序如下:

    1. 递归下降到段树中,直到找到完全由范围
    2. 覆盖的节点
    3. 修改节点的待定值
    4. 查询

      回答范围查询的过程将是:

      1. 递归下降到段树中,直到找到完全由范围
      2. 覆盖的节点
      3. 如果节点的挂起值大于最小正值,则递归更新节点的属性
      4. 复杂性

        由于每个节点只能变为负一次,我相信整个过程应该是O(nlogn + qlogn),其中n是序列的长度,q是操作的数量。

        实施例

        假设我们有数组[1,5,-3,4]。

        我们将使用以下分段节点:

        [1,5,-3,4] min positive 1, pending change 0
        [1,5] min positive 1, pending change 0
        [-3,4] min positive 4, pending change 0
        

        假设我们想要减去2来更新整个范围,我们将其更改为:

        [1,5,-3,4] min positive 1, pending change 2.
        

        现在,由于挂起的更改是> =最小正数,我们需要通过递归地将更改推送到左子项和右子项来修复节点。

        首先,左边的孩子会改为:

        [1,5] min positive 1, pending change 2
        

        然后我们将再次展开此节点并将更新应用于

        [-1,3] min positive 3, pending change 0
        

        接下来,我们会来到正确的孩子,这将改为

        [-3,4] min positive 4, pending change 2
        

        但是不需要进一步递归作为待定更改<最小的积极。

        最后,递归将再次到达顶级节点。我们使用左右子项的属性来计算现在最小正数为2(来自右小孩的最小4和等待2给出4-2 = 2的结果),我们可以将挂起的变化重置为0因为它已经适用于孩子们。

答案 1 :(得分:-3)

易于编码的数据结构称为Segment-tree 更快但更难编码的数据结构称为二进制索引树。