Java 中线段树的懒惰传播

2025年5月13日 | 阅读 9 分钟

Java 中的线段树懒惰传播话题是 Java 中线段树话题的延续。建议读者先阅读线段树话题。线段树中的懒惰传播意味着推迟某些值的更新,只在需要时才更新它们。

更新操作

让我们回顾一下线段树的更新操作。

  1. 从线段树的根开始。
  2. 如果当前节点的范围不包含输入数组的索引,则返回。
  3. 否则,更新当前节点,并从步骤 2 开始为当前节点的子节点重复操作。
Lazy Propagation in Segment Tree in Java

懒惰传播的场景

让我们讨论一个应该使用懒惰传播技术的场景。

假设任务是从索引 1 到 4 的输入数组的每个元素中添加值 6。为了完成此任务,必须为索引 1 到 4 的每个元素调用 update() 方法。这些多次调用会导致更多的时间消耗。这正是懒惰传播技术发挥作用,以加快更新过程。

请注意,线段树的节点包含查询特定范围索引的结果。如果此节点的范围包含在更新操作的范围内,则必须更新该节点的所有后代。例如,如果我们考虑上面图表中值为 35 的节点,那么该节点包含索引 3 到 5 的值之和(参见上图)。如果更新的查询范围是 2 到 5,那么我们必须更新该节点及其所有后代。使用懒惰传播,我们需要更新值为 35 的节点,并通过将这些更新信息存储在称为懒惰节点或值的单独节点中来推迟其后代的更新。我们创建一个数组 lazy[] 来表示懒惰节点。数组 lazy[] 的大小与表示线段树的数组(在以下代码中为 t[])的大小相同。

该方法是将 lazy[] 数组的所有元素初始化为 0。lazy[j] 数组中的值为 0 表示节点 j 在线段树中没有待处理的更新。lazy[j] 的任何其他值(例如 v)表示在对节点 j 进行任何查询之前,必须在线段树中向节点 j 添加 v 的金额。

使用线段树懒惰传播更新节点涉及的步骤

懒惰传播的实现

观察下面的程序。

文件名:LazySegTree.java

输出

The sum of the values in the given range is: 33
The sum of the values, after updation, in the given range is: 61

下一个主题Final-arrays-in-java