MCPcopy Create free account
hub / github.com/TheAlgorithms/Python / SegmentTree

Class SegmentTree

data_structures/binary_tree/non_recursive_segment_tree.py:47–116  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

45
46
47class SegmentTree[T]:
48 def __init__(self, arr: list[T], fnc: Callable[[T, T], T]) -> None:
49 """
50 Segment Tree constructor, it works just with commutative combiner.
51 :param arr: list of elements for the segment tree
52 :param fnc: commutative function for combine two elements
53
54 >>> SegmentTree(['a', 'b', 'c'], lambda a, b: f'{a}{b}').query(0, 2)
55 'abc'
56 >>> SegmentTree([(1, 2), (2, 3), (3, 4)],
57 ... lambda a, b: (a[0] + b[0], a[1] + b[1])).query(0, 2)
58 (6, 9)
59 """
60 any_type: Any | T = None
61
62 self.N: int = len(arr)
63 self.st: list[T] = [any_type for _ in range(self.N)] + arr
64 self.fn = fnc
65 self.build()
66
67 def build(self) -> None:
68 for p in range(self.N - 1, 0, -1):
69 self.st[p] = self.fn(self.st[p * 2], self.st[p * 2 + 1])
70
71 def update(self, p: int, v: T) -> None:
72 """
73 Update an element in log(N) time
74 :param p: position to be update
75 :param v: new value
76
77 >>> st = SegmentTree([3, 1, 2, 4], min)
78 >>> st.query(0, 3)
79 1
80 >>> st.update(2, -1)
81 >>> st.query(0, 3)
82 -1
83 """
84 p += self.N
85 self.st[p] = v
86 while p > 1:
87 p = p // 2
88 self.st[p] = self.fn(self.st[p * 2], self.st[p * 2 + 1])
89
90 def query(self, left: int, right: int) -> T | None:
91 """
92 Get range query value in log(N) time
93 :param left: left element index
94 :param right: right element index
95 :return: element combined in the range [left, right]
96
97 >>> st = SegmentTree([1, 2, 3, 4], lambda a, b: a + b)
98 >>> st.query(0, 2)
99 6
100 >>> st.query(1, 2)
101 5
102 >>> st.query(0, 3)
103 10
104 >>> st.query(2, 3)

Callers 1

Calls

no outgoing calls

Tested by

no test coverage detected