1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
| class SegmentTree: def __init__(self, nums) -> None: self.n = len(nums) self.nums = nums self.tree = [0] * (4 * self.n) self.lazy = [0] * (4 * self.n) self.build(1, self.n, 1)
def build(self, start, end, idx): if start == end: self.tree[idx] = self.nums[start - 1] return mid = start + ((end - start) >> 1) self.build(start, mid, idx << 1) self.build(mid + 1, end, idx << 1 | 1) self.pushup(idx)
def query(self, start, end, idx, left, right):
if left <= start and right >= end: return self.tree[idx] mid, sum = start + ((end - start) >> 1), 0 self.pushdown(idx, mid - start + 1, end - mid) if left <= mid: sum += self.query(start, mid, idx << 1, left, right) if right > mid: sum += self.query(mid + 1, end, idx << 1 | 1, left, right) return sum
def update(self, start, end, idx, left, right, val):
if left <= start and right >= end: self.tree[idx] += (end - start + 1) * val self.lazy[idx] += val return mid = start + ((end - start) >> 1) self.pushdown(idx, mid - start + 1, end - mid) if left <= mid: self.update(start, mid, idx << 1, left, right, val) if right > mid: self.update(mid + 1, end, idx << 1 | 1, left, right, val) self.pushup(idx)
def pushup(self, idx): self.tree[idx] = self.tree[idx << 1] + self.tree[idx << 1 | 1]
def pushdown(self, idx, ln, rn): if self.lazy[idx] != 0: self.tree[idx << 1] += self.lazy[idx] * ln self.tree[idx << 1 | 1] += self.lazy[idx] * rn self.lazy[idx << 1] += self.lazy[idx] self.lazy[idx << 1 | 1] += self.lazy[idx] self.lazy[idx] = 0
|