分段树易于移位

时间:2015-12-18 11:21:41

标签: algorithm data-structures avl-tree segment-tree

我需要基于Segment Tree的数据结构,但与clasical segment tree有一点不同。 DS应支持轻松移动元素。我的意思是我希望有能力的ds:

  • 对细分进行查询(即从索引l到索引r的元素总和)
  • 在任何索引之前插入新元素,然后移动新元素右侧的所有元素

如果所有这些操作都可以在O(logn)中运行,那就太好了 问候

1 个答案:

答案 0 :(得分:2)

是的,但不确定你能保持树的平衡。

基本结构是这样的。每个节点仅跟踪它跟踪的间隔的开始与其子节点之间的分隔之间的距离。例如,如果节点保持间隔[A,B]并且子节点保持[A,C]和[C + 1,B],那么第一个节点应该只存储信息C-A。这将允许您轻松更改间隔的大小而不必弄乱整个结构。这也意味着当你将任何内部移动并且每个迭代器跟踪间隔时,你使任何现有的迭代器无效。

进行轮班操作:

  • 搜索插入点。
  • 在路径上选择一个合适的节点。
  • 在所选节点上方插入新节点。此节点应包含旧的+新间隔。因此,将它的分割值设置为移位的大小。现在,新的空间是左边的孩子,旧空间是正确的孩子。
  • 添加您要为新空间保留的所有孩子。
  • 更新分割点位于左侧的所有父项,因为现在分割前有更多值。

任何其他操作都应该相同。您应该选择一个节点,其中新间隔大致等于节点的大小,以便保留操作的O(logn)。显然,一次又一次地插入1个元素会导致某些路径比其他路径长得多,除非您在执行移位后添加一个步骤来重新平衡树。

但是,如果你知道之前的转变,我只会向后调整转移并计算所有数据和查询O(N)的最终位置。然后你可以简单地做一个常规的分段树而不用担心轮班。