具有修改的树路径上的查询

时间:2017-07-08 19:05:32

标签: algorithm tree time-complexity depth-first-search lowest-common-ancestor

问题:

您将获得一棵树,其中 n个节点(可以高达10 ^ 5 )和 n-1双向边。并且假设每个节点包含两个值:

  1. 它是索引(只是节点的唯一编号),假设它从1到n。
  2. 它的值 Vi ,可以从 1到10 ^ 8
  3. 现在在同一棵树上会有多种相同类型的查询(查询数量最多可达10 ^ 5 ),如下所示:

    1. 您将获得node1,node2和值 P (可以从 1到10 ^ 8 )。
    2. 对于每种类型的查询,您只需要查找从node1到node2的路径中的节点数,其值小于P

      注意:所有节点之间将存在唯一路径,并且没有两条边属于同一对节点。

      所需的时间复杂度O(nLog(n))或者可以是其他术语,但在给定约束条件下应该在1秒内可解决。

      我尝试了什么:

      (A)。如果通过在每个节点存储以下信息在O(nLog(n))中使用LCA方法修复P的值,我可以很容易地解决它:

      1. 从根到给定节点的值小于P的节点数。
      2. 但是这里的P变化太大,所以这无济于事。

        (B)。我想的其他方法是使用简单的DFS。但这也需要O(nq),其中q是查询数。同样,因为n和q都在1到10 ^ 5之间变化,所以这在给定的时间约束下也没有帮助。

        我想不出别的。任何帮助,将不胜感激。 :)

        来源:

        我想在SPOJ的某个地方读到这个问题。但现在找不到它。尝试在网上搜索但无法在任何地方找到解决方案(Codeforces,CodeChef,SPOJ,StackOverflow)。

1 个答案:

答案 0 :(得分:2)

  1. ans(v, P)成为从根到v的垂直路径和P的给定值的答案。

  2. 我们如何计算它?有一个简单的离线解决方案:我们可以将给定节点的所有查询存储在与之关联的向量中,运行深度优先搜索将所有值保留在数据结构中可以执行以下操作的路径的当前路径上:

    • 添加值
    • 删除值
    • 计算小于X
    • 的数字元素

    任何平衡的二元搜索树都可以。您可以使其更简单:如果您事先知道所有查询,则可以压缩数字以使它们处于[0..n - 1]范围内并使用二进制索引树。

  3. 回到原来的问题:(u, v, P)查询的答案显然是ans(v, P) + ans(u, P) - 2 * ans(LCA(u, v), P)

  4. 就是这样。时间复杂度为O((N + Q) log N)