307. 区域和检索 - 数组可修改
给定一个整数数组 nums,求出数组从索引 i 到 j (i ≤ j) 范围内元素的总和,包含 i, j 两点。
update(i, val) 函数可以通过将下标为 i 的数值更新为 val,从而对数列进行修改。
示例:
Given nums = [1, 3, 5]
sumRange(0, 2) -> 9
update(1, 2)
sumRange(0, 2) -> 8
说明:
数组仅可以在 update 函数下进行修改。
你可以假设 update 函数与 sumRange 函数的调用次数是均匀分布的。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/range-sum-query-mutable
线段树板子
class NumArray: def __init__(self, nums: List[int]): self.n=len(nums) if self.n==0:return max_size= 2 ** (int(math.ceil(math.log(self.n, 2))) + 1) - 1 self.seg_tree=[0 for i in range(max_size)] self.arr=nums self.biuld_tree(0,0,self.n-1) def biuld_tree(self,node,start,end): if start==end: self.seg_tree[node]=self.arr[start] return mid=(start+end)//2 left_node=2*node+1 right_node=left_node+1 self.biuld_tree(left_node,start,mid) self.biuld_tree(right_node,mid+1,end) self.seg_tree[node]=self.seg_tree[left_node]+self.seg_tree[right_node] def update(self, i: int, val: int) -> None: def update_tree(node,start,end,idx,val): if start==end: self.seg_tree[node]=self.arr[idx]=val return mid=(start+end)//2 left_node=2*node+1 right_node=left_node+1 if start<=idx<=mid: update_tree(left_node,start,mid,idx,val) else: update_tree(right_node,mid+1,end,idx,val) self.seg_tree[node]=self.seg_tree[left_node]+self.seg_tree[right_node] update_tree(0,0,self.n-1,i,val) def sumRange(self, i: int, j: int) -> int: def query_tree(node,start,end,l,r): if l>end or r<start:return 0 elif l<=start and end<=r:return self.seg_tree[node] elif start==end:return self.seg_tree[node] mid=(start+end)//2 left_node=2*node+1 right_node=left_node+1 sum_left=query_tree(left_node,start,mid,l,r) sum_right=query_tree(right_node,mid+1,end,l,r) return sum_left+sum_right return query_tree(0,0,self.n-1,i,j) # Your NumArray object will be instantiated and called as such: # obj = NumArray(nums) # obj.update(i,val) # param_2 = obj.sumRange(i,j)