📅  最后修改于: 2023-12-03 15:22:38.181000             🧑  作者: Mango
分段树(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方法即可进行更新和查询操作。