#!/usr/bin/env python3 """307""" from typing import List class NumArray_Naive: """Naive implementation. Useless.""" def __init__(self, nums: List[int]): self.nums = nums def update(self, index: int, val: int) -> None: """Update.""" self.nums[index] = val def sumRange(self, left: int, right: int) -> int: """sumRange.""" return sum(self.nums[left : right + 1]) class NumArray: """Segment Tree implementation.""" def __init__(self, nums: List[int]): self.nums = nums self.n = len(nums) self.segment_tree = [0] * (len(nums) * 2) self.build_segment_tree() def build_segment_tree(self): """build segment tree.""" for i, j in zip(range(self.n, 2 * self.n), range(0, len(self.nums))): self.segment_tree[i] = self.nums[j] for i in reversed(range(1, self.n)): self.segment_tree[i] = ( self.segment_tree[i * 2] + self.segment_tree[i * 2 + 1] ) # print(self.segment_tree) def update_segment_tree(self, index: int, val: int): """update segment tree.""" pos: int = index + self.n self.segment_tree[pos] = val while pos > 0: left = pos right = pos if pos % 2 == 0: right = pos + 1 else: left = pos - 1 self.segment_tree[int(pos / 2)] = ( self.segment_tree[left] + self.segment_tree[right] ) pos = int(pos / 2) def update(self, index: int, val: int) -> None: """Update.""" self.update_segment_tree(index, val) def sumRange(self, left: int, right: int) -> int: """sumRange.""" l = left + self.n r = right + self.n s: int = 0 while l <= r: if (l % 2) == 1: s += self.segment_tree[l] l += 1 if (r % 2) == 0: s += self.segment_tree[r] r -= 1 l = int(l / 2) r = int(r / 2) return s # Your NumArray object will be instantiated and called as such: # obj = NumArray(nums) # obj.update(index,val) # param_2 = obj.sumRange(left,right) def main(): """Main.""" num_array = NumArray([1, 3, 5]) print(num_array.sumRange(0, 2)) num_array.update(1, 2) print(num_array.sumRange(0, 2)) if __name__ == "__main__": main()