Segment Tree

Cosider using other algorithms before using it.
A solution for leetcode 699: Falling Squares

  1. class SegTree:
  2. def __init__(self, nums: List[int]):
  3. # init the tree with intervals, nums can be sorted endpoints of them
  4. k = len(nums)
  5. if k <= 1:
  6. self.n = 0
  7. return
  8. k -= 1
  9. self.n = n = int(math.pow(2,int(math.ceil(math.log(k,2)))))
  10. self.data = data = [[0,0,0,0] for i in range(2*n)] # [left, right, data1, data2]
  11. data[n:n+k] = [[nums[i],nums[i+1],0,0] for i in range(k)] # intervals of the leaves
  12. for i in range(n-1,0,-1):
  13. data[i][1] = max(data[2*i][1], data[2*i+1][1])
  14. data[i][0] = data[2*i][0]
  15. def update(self, i: int, j: int, val: int, start: int=1) -> None:
  16. # there can be two cases:
  17. # 1. update a node, then update bottom up (starting from one of the leaves)
  18. # 2. update an interval, then update top down (starting from the root)
  19. if start >= 2* self.n:
  20. return
  21. l,r = self.data[start][:2]
  22. if j <= l or i >= r:
  23. return
  24. self.data[start][2] = max(val, self.data[start][2]) # max height
  25. if i <=l and j >= r:
  26. self.data[start][3] = max(val, self.data[start][3]) # min height
  27. return
  28. if start >= self.n:
  29. return
  30. self.update(i, j, val, 2 * start)
  31. self.update(i, j, val, 2 * start + 1)
  32. def query(self, i: int, j: int, begin:int = 1) -> int:
  33. # there can be two cases:
  34. # 1. query one interval
  35. # 2. query one point
  36. if begin >= 2* self.n:
  37. return 0
  38. l,r = self.data[begin][:2]
  39. if j <= l or i >= r:
  40. return 0
  41. if i <= l and j >= r:
  42. return self.data[begin][2]
  43. return max(self.data[begin][3], self.query(i,j,2*begin),self.query(i,j,2*begin+1))

Fenwick Tree

It is also called Binary Indexed Tree (树状数组)
The problem can be soved by this often can be solved by segment tree.

Implementation

image.png
n的二进制最后一个1对应的值为: lowbit(n) = n&(-n)

注意起始从1开始,不是从0开始

  1. class FenwickTree:
  2. def __init__(self, n):
  3. self.sum_array = [0] * (n + 1)
  4. self.n = n
  5. def lowbit(self, x):
  6. return x & -x
  7. def add(self, x, val):
  8. while x <= self.n:
  9. self.sum_array[x] += val
  10. x += self.lowbit(x)
  11. def sum(self, x):
  12. res = 0
  13. while x > 0:
  14. res += self.sum_array[x]
  15. x -= self.lowbit(x)
  16. return res

Problems

Leetcode 493: 链接
Leetcode 315: Count of Smaller Numbers After Self
Leetcode 327: count of range sum

Prefix Tree