【问题标题】:Reversing an array Query反转数组查询
【发布时间】:2015-10-06 09:22:05
【问题描述】:

我有一个大小为 N 的数组,我给出了 2 种类型的查询

1 L R 反转 [L,R] 中的所有元素
2 L 查找索引 L 处的值。

Example: [1,2,3,4,5]
1 2 4   -> [1,4,3,2,5]
1 4 5   -> [1,4,3,5,2]
2 5    -> 2

Q-查询次数
Q
直截了当的解决方案将是 O(Q*N) 这将是相当慢的,如何使它更快可以使用分段树?

【问题讨论】:

  • 是的。段树是解决问题的方法。
  • @vish4071 到底怎么样?你能发表一个答案吗? :)
  • @vish4071 你能解释一下如何在这个中使用段树
  • @svs 任何帮助!!!关于线段树的使用
  • 无论如何,您将在类型 1(Q1) 的查询和类型 2(Q2) 运行时的查询之间进行权衡。在朴素的解决方案中,Q1 将采用 O(n),而 Q2 将采用 O(1)。您究竟想最小化什么?

标签: algorithm data-structures tree


【解决方案1】:

我不确定分段树算法是什么样的。

这可以使用装饰的展开树在 O((n + q) log n) 时间内完成。每个节点装饰由一个后代计数和一个位组成,当设置时,它会隐式翻转整个子树。要查询,请使用后代计数导航到正确的节点。要从u 反转到v,将u 展开到根,分离其左子树u.L,展开v 到根,分离其右子树v.R,反转所有的翻转位u.Lvv.R,将u.L重新附加到v.R所在的字段,展开u,以类似方式重新附加v.R

Key: ? denotes an anonymous node
     ^ denotes a subtree


   u
  / \
u.L  ?
 ^  / \
   v   ?
   ^   ^


u.L    v
 ^    / \
     u  v.R
      \  ^
       ?
       ^


v.R    v     # v's flip bit is inverted
 ^    / \
     u  u.L  # so is u.L's, for no effect on u.L
      \  ^
       ?
       ^


   u
  / \
v.R  v
 ^  / \
   ?  u.L
   ^   ^

【讨论】:

  • 1) 抱歉,您如何准确执行第二种查询?看不到它。 2)您是否将元素的索引存储在树节点中? 3)decorated你的意思是增强,这意味着它存储的附加信息不同于左、右孩子? 4)知道伸展树的类似应用吗?它们似乎是非常强大的工具
  • @svs 1. 添加了图表。 2. 是的,每个节点都包含一个数据值。 3. 是的。 4. Sleator--Tarjan的原论文里有一堆应用。
  • 我不明白为什么我们最终让u.R 成为u 的左孩子。我发现以下问题:让我们查询索引小于u 的东西,比如说p < u。此时u 是根,我们看到p < uu 的反转标志也是错误的,这意味着我们应该向左走。但是当我们向左走时,我们进入子树v.R,其中每个元素都大于v,而v本身大于u。这意味着我们将提取一些东西 > u 但我们想要 p < u
  • @svs 如果有帮助,我通常会考虑拆分序列、反转整个序列以及将序列连接在一起。我实际上已经实现了这一点,所以我保证这是可能的。
  • 我相信这是可能的,但不明白为什么v.R 应该是u 的左孩子而u.L - v 是右孩子。不应该是相反的吗?
猜你喜欢
  • 1970-01-01
  • 2020-02-19
  • 1970-01-01
  • 2023-01-13
  • 1970-01-01
  • 1970-01-01
  • 2018-02-09
  • 1970-01-01
相关资源
最近更新 更多