Segment Tree
Cosider using other algorithms before using it.
A solution for leetcode 699: Falling Squares
class SegTree:
def __init__(self, nums: List[int]):
# init the tree with intervals, nums can be sorted endpoints of them
k = len(nums)
if k <= 1:
self.n = 0
return
k -= 1
self.n = n = int(math.pow(2,int(math.ceil(math.log(k,2)))))
self.data = data = [[0,0,0,0] for i in range(2*n)] # [left, right, data1, data2]
data[n:n+k] = [[nums[i],nums[i+1],0,0] for i in range(k)] # intervals of the leaves
for i in range(n-1,0,-1):
data[i][1] = max(data[2*i][1], data[2*i+1][1])
data[i][0] = data[2*i][0]
def update(self, i: int, j: int, val: int, start: int=1) -> None:
# there can be two cases:
# 1. update a node, then update bottom up (starting from one of the leaves)
# 2. update an interval, then update top down (starting from the root)
if start >= 2* self.n:
return
l,r = self.data[start][:2]
if j <= l or i >= r:
return
self.data[start][2] = max(val, self.data[start][2]) # max height
if i <=l and j >= r:
self.data[start][3] = max(val, self.data[start][3]) # min height
return
if start >= self.n:
return
self.update(i, j, val, 2 * start)
self.update(i, j, val, 2 * start + 1)
def query(self, i: int, j: int, begin:int = 1) -> int:
# there can be two cases:
# 1. query one interval
# 2. query one point
if begin >= 2* self.n:
return 0
l,r = self.data[begin][:2]
if j <= l or i >= r:
return 0
if i <= l and j >= r:
return self.data[begin][2]
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
n的二进制最后一个1对应的值为: lowbit(n) = n&(-n)
注意起始从1开始,不是从0开始
class FenwickTree:
def __init__(self, n):
self.sum_array = [0] * (n + 1)
self.n = n
def lowbit(self, x):
return x & -x
def add(self, x, val):
while x <= self.n:
self.sum_array[x] += val
x += self.lowbit(x)
def sum(self, x):
res = 0
while x > 0:
res += self.sum_array[x]
x -= self.lowbit(x)
return res
Problems
Leetcode 493: 链接
Leetcode 315: Count of Smaller Numbers After Self
Leetcode 327: count of range sum