题目:原题链接(困难)
标签:线段树、有序映射
解法 | 时间复杂度 | 空间复杂度 | 执行用时 |
---|---|---|---|
Ans 1 (Python) | 每次操作 = O ( l o g K ) O(logK) O(logK) | 每次操作 = O ( l o g K ) O(logK) O(logK) | 3036ms (5.71%) |
Ans 2 (Python) | |||
Ans 3 (Python) |
解法一:
class SegmentTreeForBivalent:
"""二值线段树:区域查询和更新最大值"""
class _Node:
"""线段树结点"""
__slots__ = "start", "end", "val", "left", "right"
def __init__(self, start, end):
self.start = start # 左侧边界(包含)
self.end = end # 右侧边界(包含)
self.left = None # 结点左子结点
self.right = None # 结点右子节点
self.val = False # 当前结点最小值
def __init__(self, size):
"""初始化线段树实例"""
self.root = self._Node(0, size)
def _update(self, node, pos1, pos2, data):
"""更新数据"""
# 当前区间正好为当前结点的情况:即不需要继续分裂的情况
if node.start == pos1 and node.end == pos2:
node.val = data
node.left, node.right = None, None
# 当前区间为当前结点的部分的情况:即需要继续分裂的情况
else:
mid = (node.start + node.end) // 2
# 创建两个子结点
if node.left is None:
node.left = self._Node(node.start, mid)
node.left.val = node.val
if node.right is None:
node.right = self._Node(mid + 1, node.end)
node.right.val = node.val
# 更新当前结点的子结点
if pos2 <= mid:
self._update(node.left, pos1, pos2, data)
elif pos1 >= mid + 1:
self._update(node.right, pos1, pos2, data)
else:
self._update(node.left, pos1, mid, data)
self._update(node.right, mid + 1, pos2, data)
# 更新当前结点的值
node.val = node.left.val and node.right.val
def _query(self, node, start, end):
"""查询数据"""
# 当前区间正好为当前结点的情况:即不需要继续分裂的情况
if node.start == start and node.end == end:
return node.val
# 当前结点没有子结点的情况:即当前结点下所有位置的结果一致的情况
elif node.left is None and node.right is None:
return node.val
# 当前区间为当前结点的部分的情况:即需要继续分裂的情况
else:
mid = (node.start + node.end) // 2
# 查询当前结果的最小值
if end <= mid:
return self._query(node.left, start, end)
elif start >= mid + 1:
return self._query(node.right, start, end)
else:
return self._query(node.left, start, mid) and self._query(node.right, mid + 1, end)
def query_one(self, query):
return self._query(self.root, query, query)
def query_range(self, start, end):
return self._query(self.root, start, end)
def update_one(self, query, data):
self._update(self.root, query, query, data)
def update_range(self, start, end, data):
self._update(self.root, start, end, data)
class RangeModule:
def __init__(self):
self.tree = SegmentTreeForBivalent(10 ** 9)
def addRange(self, left: int, right: int) -> None:
self.tree.update_range(left, right - 1, True)
def queryRange(self, left: int, right: int) -> bool:
return self.tree.query_range(left, right - 1)
def removeRange(self, left: int, right: int) -> None:
self.tree.update_range(left, right - 1, False)