堆栈

2015-03-02 118 views
-4

执行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查询,怎么做这个问题。

我们无法一次又一次更新所有元素。所以请提供有效的解决方案。

+6

“请尽我的功课,并高效地在你的时间” – tux3 2015-03-02 12:30:04

+0

@ tux3它似乎功课? – user3840069 2015-03-02 12:31:09

+0

@ tux3我的坏!但它不是 – user3840069 2015-03-02 12:31:26

回答

0

将会有比弹出操作更多的推动,否则堆栈将最终为空。寻找最后一个没有相应弹出窗口的按钮,这是最后会在堆栈顶部的元素。现在简单地为每个适当的公司操作增加这个元素。

复杂度的这种方法:

O(2n)后计算

O(查询)存储器

N =所有的操作的总数查询

+0

给出多个查询。 – IVlad 2015-03-02 12:55:07

+0

提供此方法失败的示例。多个查询可以“粘贴”在一起,不是吗? – ShellFish 2015-03-02 13:03:30

+0

我不认为它失败了,我认为它不一定有效。你如何“为每个适当的公司增加这个元素”? – IVlad 2015-03-02 13:37:55

1

我们可以用一个segment tree那在O(log n)支持您所需的操作:

  1. 增量在给定的范围内

所有元素对于您的段树的间隔相关联的每个节点包含在给定范围内,增加一个计数器num_increments吧:这个计数器会告诉你多少次,元素在这个范围内都增加了。只有为最顶级的节点做这件事,一旦你做完这些,不要递归地回到他们的孩子身上。

  • 查询给定索引
  • 这个问题的答案是v[index] + number_of_increments处的值。您可以通过在分段树中查找与索引关联的节点并在走向它时跟踪其父节点的值来找到增量的数量。

    有一对夫妇的事情要考虑,这取决于您的具体问题:

    1. 对于给定的L, R,也许设定R = min(R, stack.Size),因为它是没有意义的堆栈增加的元素还没有。或者它可以解决你的问题,我不知道。如果它确实对你的问题有意义,它会让事情变得更容易,并使我的第二点失效;

    2. 当你从堆栈中弹出一个元素时会发生什么?此方法仍然会将其位置标记为递增,因此如果将其后移一位,则会考虑将其递增1.考虑如何还可以支持给定索引的递减(与查询操作类似)。

    增量方向由x代替1应该很容易实现。

    +0

    使用前构建这棵树的复杂性是什么? – ShellFish 2015-03-02 14:34:00

    +0

    @ShellFish - O(n)因为最初没有增量:只需声明一个足够容纳树的数组即可。 – IVlad 2015-03-02 14:37:44

    +0

    日志(n)花费一次性成本还是每次操作/查询?如果前者是真的,那么这是一个很好的解决方案! – ShellFish 2015-03-02 14:41:57