实现
class SegmentTree: def __init__(self, data: list): # 线段树 self.tree = [None for i in range(len(data) * 4)] self.data = [i for i in data] def get_size(self): return len(self.data) def get(self, index: int): assert 0 <= index < len(self.data), "index error" return self.data[index] @staticmethod def get_left_child(index): """ 左孩子节点下标""" return 2 * index + 1 @staticmethod def get_right_child(index): """右孩子节点下标""" return 2 * index + 2 def build_segment_tree(self): self.__build_segment_tree(0, 0, len(self.data) - 1) # 在tree_index的位置创建表示区间[l,r]的线段树 def __build_segment_tree(self, tree_index, l: int, r: int): if l == r: self.tree[tree_index] = self.data[l] return # 左下标 left_index = self.get_left_child(tree_index) # 右下标 right_index = self.get_right_child(tree_index) mid = l + (r - l) // 2 self.__build_segment_tree(left_index, l, mid) self.__build_segment_tree(right_index, mid + 1, r) self.tree[tree_index] = self.tree[left_index] + self.tree[right_index] def query(self, query_l, query_r): return self.__query(0, 0, len(self.data) - 1, query_l, query_r) # 在以tree_index 为根的线段树中[l..r]的范围内,搜索区间[query_l,query_r]的值 def __query(self, tree_index, l, r, query_l, query_r): if l == query_l and r == query_r: return self.tree[tree_index] mid = l + (r - l) // 2 left_tree_index = self.get_left_child(tree_index) right_tree_index = self.get_right_child(tree_index) if query_l >= (mid + 1): return self.__query(right_tree_index, mid + 1, r, query_l, query_r) elif query_r <= mid: return self.__query(left_tree_index, l, mid, query_l, query_r) left_res = self.__query(left_tree_index, l, mid, query_l, mid) right_res = self.__query(right_tree_index, mid + 1, r, mid + 1, query_r) return left_res + right_res # 修改数据 def set(self, index, value): self.data[index] = value self.__set(0, 0, len(self.data)-1, index, value) def __set(self, tree_index, l, r, index, value): if l == r: self.tree[tree_index] = value return mid = l + (r - l) // 2 left_tree_index = self.get_left_child(tree_index) right_tree_index = self.get_right_child(tree_index) if index >= mid + 1: self.__set(right_tree_index, mid + 1, r, index, value) else: self.__set(left_tree_index, l, mid, index, value) self.tree[tree_index] = self.tree[left_tree_index] + self.tree[right_tree_index]