📜  分段树中的延迟传播套装2(1)

📅  最后修改于: 2023-12-03 15:22:38.181000             🧑  作者: Mango

分段树中的延迟传播套装2

简介

分段树(Segment Tree)是一种二叉树结构,用来解决一维区间查询问题。延迟传播(Lazy Propagation)是一种优化技巧,用来减少分段树的更新时间复杂度。分段树中的延迟传播套装2就是将这两种技巧结合起来使用。

实现方式

分段树的节点包含三个属性:左右子节点、节点维护的区间范围、节点维护的值。每一个节点都会维护一个lazy tag,当这个节点被更新时,lazy tag会被标记为需要传递给子节点的值。这个标记的传递就是lazy propagation。

当更新一个区间时,我们首先访问了这个区间的范围并计算出一个值。这个值会被覆盖到这个区间的所有叶子节点上。如果这个区间的范围小于要更新的区间,那么这个区间里的左右两个子节点就会被打上lazy tag,并且这个tag的值就是这个区间的值(也就是要更新的值)。之后,这个更新操作会传递给这个区间的左右子节点,直到覆盖所有需要更新的区间。

查询操作和普通的查询操作一样,但是需要将每个节点上的lazy tag传递下去,直到覆盖到需要查询的区间。这样查询到的值才是正确的。

代码示例

这里为了展示方便,使用Python3语言实现了分段树中的延迟传播套装2。

from collections import deque

class SegmentTree:
    def __init__(self, lst: list):
        self.build(lst)

    # Build the segment tree from a list
    def build(self, lst: list) -> None:
        queue = deque()
        for i in range(len(lst)):
            queue.append(Node(i, i, lst[i]))
        while len(queue) > 1:
            node1 = queue.popleft()
            node2 = queue.popleft()
            parent = Node(node1.start, node2.end)
            parent.left = node1
            parent.right = node2
            queue.append(parent)
        self.root = queue.popleft()

    # Update the interval [start, end] with value val
    def update(self, start: int, end: int, val: int) -> None:
        self._update(self.root, start, end, val)

    def _update(self, node, start, end, val):
        if node.end < start or node.start > end:
            return
        if node.start >= start and node.end <= end:
            node.val = val
            node.lazy = val
            return
        if node.lazy:
            self._propagate(node)
        self._update(node.left, start, end, val)
        self._update(node.right, start, end, val)
        node.val = min(node.left.val, node.right.val)

    # Query the interval [start, end]
    def query(self, start: int, end: int) -> int:
        return self._query(self.root, start, end)

    def _query(self, node, start, end):
        if node.end < start or node.start > end:
            return float('inf')
        if node.start >= start and node.end <= end:
            return node.val
        if node.lazy:
            self._propagate(node)
        return min(self._query(node.left, start, end), self._query(node.right, start, end))

    # Propagate lazy tags down to child nodes
    def _propagate(self, node):
        node.left.val = node.lazy
        node.left.lazy = node.lazy
        node.right.val = node.lazy
        node.right.lazy = node.lazy
        node.lazy = None

# Node class for the Segment Tree
class Node:
    def __init__(self, start, end, val=None):
        self.start = start
        self.end = end
        self.val = val
        self.lazy = None
        self.left = None
        self.right = None

这段代码里面包含了分段树的建树、更新、查询以及延迟传播等功能。使用方法也非常简单,只需要创建一个SegmentTree类型的对象,然后调用它的update和query方法即可进行更新和查询操作。