我得到一个空堆栈,我需要支持三个操作:
PUSH x : Push element x onto the stack
POP : Pop the top element
INC L R x : Increment the L to R elements by x
在每次查询之后,我需要告诉数组的顶部元素。如果他们可以进行10 ^ 6次查询,如何解决这个问题。
我们无法一次又一次地更新所有元素。所以请提供有效的解决方案。
答案 0 :(得分:1)
我们可以在O(log n)
中使用支持您所需操作的segment tree:
对于与给定范围中包含的间隔关联的细分树中的每个节点,为其递增计数器num_increments
:此计数器将告诉您此范围内的元素全部递增的次数。只对最顶端的此类节点执行此操作,一旦完成此操作,请不要递归地转到他们的孩子。
答案是v[index] + number_of_increments
。您可以通过在段树中查找与索引关联的节点并跟踪其父项来查找增量数。当你走到它时,num_increments
值。
根据您的确切问题,有几件事需要考虑:
对于给定的L, R
,可能设置R = min(R, stack.Size)
,因为增加堆栈中尚未存在的元素是没有意义的。或者也许这对你的问题有用,我不知道。如果它确实对你的问题有意义,它会使事情变得更容易,并且它使我的第二点无效;
从堆栈中弹出元素会发生什么?此方法仍然会将其位置标记为递增,因此如果您向后推一个,则会认为它增加1.想想您如何也可以支持给定索引的减量(它类似于查询操作)。
x
而不是1
的增量应该很容易实现。
答案 1 :(得分:0)
将会有比弹出操作更多的推送,否则堆栈最终会为空。寻找没有相应pop的最后一次推送,这是最后将在堆栈顶部的元素。现在只需为每个适当的inc操作增加此元素。
此方法的复杂性:
O(2n)计算
O(查询)内存
n =所有查询的总操作数