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)

 

posted @ 2020-09-10 19:08  XXXSANS  阅读(185)  评论(0编辑  收藏  举报