Add a lazy array alongside the tree array:
class LazySegmentTree:
def __init__(self, n):
self.n = n
self.tree = [0] * (4 * n)
self.lazy = [0] * (4 * n)
lazy[node] stores pending updates that haven't been propagated to children yet.
For "add to range": lazy[node] means "add to all elements in this node's range."
Before accessing a node's children, always push down any lazy value first. This guarantees correctness.