static@method v.s. classmethod v.s. instanc emethod
class SegmentTreeNode(object):
def __init__(self, s, e):
self.start = s # start end point
self.end = e # end endpoint
self.total = 0 # total sum within range [start, end] inclusive
self.left = None # left subtree
self.right = None # right substree
@staticmethod
def build_tree(A, s, e):
if s > e:
return None
node = SegmentTreeNode(s,e)
if s == e:
node.total = A[s]
else:
mid = (s+e)//2
node.left = SegmentTreeNode.build_tree(A,s,mid)
node.right = SegmentTreeNode.build_tree(A,mid+1,e)
node.total = node.left.total + node.right.total
return node
def update(self, i, val):
# update at position index => need to (1)find exact leaf node to update
#(2) update related parent node's total
if self.start == self.end: #== i: # target node update
self.total = val
else:
mid = (self.start + self.end)//2
if i <= mid:
self.left.update(i,val) # query range falls in left subtree
else:
self.right.update(i,val) # query range falls in right subtree
self.total = self.left.total + self.right.total # update current parent node's total
def query(self,l,r):
# termination condition: query range match current root
if self.start == l and self.end == r:
return self.total
else:
mid = (self.start + self.end)//2
if r <= mid:
return self.left.query(l,r)
elif l >= mid+1:
return self.right.query(l,r)
else:
# otherwise inteval is split => need to calculate sum recursively
# by splitting interval
return self.left.query(l,mid) + self.right.query(mid+1,r)
class NumArray(object):
"""
create tree tc O(N) sc O(N)
update tree tc O(lgN)
query : tc O(lgN) worst case for query tc O(N)
"""
def __init__(self, nums: List[int]):
self.root = SegmentTreeNode.build_tree(nums, 0, len(nums)-1)
def update(self, index: int, val: int) -> None:
self.root.update(index,val)
def sumRange(self, left: int, right: int) -> int:
return self.root.query(left,right)