Segment Tree
- Used for Range Queries
- Stored as a segment tree array left=> 2r+1, right=> 2r+2
- Segment Tree size is 2n; 4n preffered
- Is a Balanced Binary Tree
Possible Queries
Must be associative
f(f(a,b), c) == f(a, f(b,c))
decomposable
the answer for a range; built from answers of sub-rangesExample
- Sum
- Min/Max
- GCD/LCM
- AND/OR/XOR
- Product
- Count
Complexity
Build => O(n) Query => O(logn) Update => O(logn)
sample
arr = [1,2,3,4,5,6,7]
n = len(arr)
# segment tree has 2n nodes
seg = [0] * 2n
def buildTree(root, start, end):
# leaf node
if start == end:
seg[root] = arr[start]
return
# recursion
mid = (start + end) // 2
buildTree(2*root + 1, start, mid)
buildTree(2*root + 2, mid+1, end)
# fill this; decides which operation in query; sum here
seg[root] = seg[2*root+1] + seg[2*root+2]
def update(root, start, end, id, val):
if start == end:
arr[id] = val
seg[root] = val
return
# recursion
mid = (start + end) // 2
if id <= mid:
update(2*root+1, start, mid, id, val)
else:
update(2*root+2, mid+1, end, id, val)
# refill
seg[root] = seg[2*root+1] + seg[2*root+2]
def query(root, start, end, l, r):
# outof bounds
if r < start or l > end:
return 0
if l <= start and r >= end:
return seg[root]
# recursion
mid = (start + end) // 2
left = query(2*root+1, start, mid, l, r)
right = query(2*root+2, mid+1, end, l, r)
return left + right
To Actually use these
arr = [1,2,3,4,5,6,7,8,9,10]
def useBuild(arr):
buildTree(0, 0, len(arr)-1)
def useUpdate(arr, id, val):
update(0, 0, len(arr)-1, id, val)
def useQuery(arr, left, right):
query(0, 0, len(arr) - 1, left, right)