【线段树模板python】也是leetcode1622

就着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)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值