执行3个行动,我给出一个空栈,我需要支持三种操作:堆栈
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查询,怎么做这个问题。
我们无法一次又一次更新所有元素。所以请提供有效的解决方案。
执行3个行动,我给出一个空栈,我需要支持三种操作:堆栈
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查询,怎么做这个问题。
我们无法一次又一次更新所有元素。所以请提供有效的解决方案。
我们可以用一个segment tree那在O(log n)
支持您所需的操作:
所有元素对于您的段树的间隔相关联的每个节点包含在给定范围内,增加一个计数器num_increments
吧:这个计数器会告诉你多少次,元素在这个范围内都增加了。只有为最顶级的节点做这件事,一旦你做完这些,不要递归地回到他们的孩子身上。
这个问题的答案是v[index] + number_of_increments
处的值。您可以通过在分段树中查找与索引关联的节点并在走向它时跟踪其父节点的值来找到增量的数量。
有一对夫妇的事情要考虑,这取决于您的具体问题:
对于给定的L, R
,也许设定R = min(R, stack.Size)
,因为它是没有意义的堆栈增加的元素还没有。或者它可以解决你的问题,我不知道。如果它确实对你的问题有意义,它会让事情变得更容易,并使我的第二点失效;
当你从堆栈中弹出一个元素时会发生什么?此方法仍然会将其位置标记为递增,因此如果将其后移一位,则会考虑将其递增1.考虑如何还可以支持给定索引的递减(与查询操作类似)。
增量方向由x
代替1
应该很容易实现。
“请尽我的功课,并高效地在你的时间” – tux3 2015-03-02 12:30:04
@ tux3它似乎功课? – user3840069 2015-03-02 12:31:09
@ tux3我的坏!但它不是 – user3840069 2015-03-02 12:31:26