我有一个长度 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有很好的了解。如果您的解决方案涉及这些数据结构,那将非常棒。
答案 0 :(得分:7)
对数据结构使用具有延迟传播的分段树。
在每个节点商店中:
更新范围的程序如下:
回答范围查询的过程将是:
由于每个节点只能变为负一次,我相信整个过程应该是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 更快但更难编码的数据结构称为二进制索引树。