就着leetcode 1622,写了一下线段树模板,凑活用
mod = int(1e9 + 7)
class SegmentTree:
def __init__(self, n):
self.tree = [0] * (4 * n)
self.lazy = [None] * (4 * n)
def update(self, t, lb, rb, l, r, op):
if l <= lb <= rb <= r:
self.lazy[t] = self.merge(self.lazy[t], op)
return
mid = (lb + rb) >> 1
if mid >= l:
self.update(t << 1, lb, mid, l, r, op)
if mid < r:
self.update(t << 1 | 1, mid + 1, rb, l, r, op)
return
def merge(self, op1, op2):
return (op1[0] * op2[0], op1[1] * op2[0] + op2[1]) if op1 else op2
def push_down(self, t, lb, rb):
if lb == rb:
self.tree[t] = (self.tree[t] * self.lazy[t][0] + self.lazy[t][1]) % mod
else:
self.lazy[t << 1] = self.merge(self.lazy[t << 1], self.lazy[t])
self.lazy[t << 1 | 1] = self.merge(self.lazy[t << 1 | 1], self.lazy[t])
self.lazy[t] = None
def query(self, t, lb, rb, p):
if self.lazy[t] != None:
self.push_down(t, lb, rb)
if lb == rb:
return self.tree[t]
mid = (lb + rb) >> 1
if p <= mid:
return self.query(t << 1, lb, mid, p)
else:
return self.query(t << 1 | 1, mid + 1, rb, p)
class Fancy:
def __init__(self):
self.N = 100000
self.n = 0
self.seg_tree = SegmentTree(self.N)
def append(self, val: int) -> None:
self.n += 1
self.seg_tree.update(1, 1, self.N, self.n, self.n, (1, val))
def addAll(self, inc: int) -> None:
if self.n == 0:
return
self.seg_tree.update(1, 1, self.N, 1, self.n, (1, inc))
def multAll(self, m: int) -> None:
if self.n == 0:
return
self.seg_tree.update(1, 1, self.N, 1, self.n, (m, 0))
def getIndex(self, idx: int) -> int:
if idx < 0 or idx >= self.n:
return -1
return self.seg_tree.query(1, 1, self.N, idx + 1)