aboutsummaryrefslogblamecommitdiffstats
path: root/307/main.py
blob: 47a941061d64b7f919caab06d2112a4bbc9e40da (plain) (tree)






























































































                                                                             
#!/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()