python,有无大佬指点一下,改了一晚上才跑过样例。。。
查看原帖
python,有无大佬指点一下,改了一晚上才跑过样例。。。
493638
隐公元年楼主2022/7/30 18:01

不是很明白,如果把lazy标记换成任务队列(暂时别管内存),这个题也应该是可以做的吧。。。 代码相当长。。。有点麻烦

import copy

n, m, p = map(int, input().split())


class node:
    def __init__(self, val, a, b, left=None, right=None, lazy=None):
        self.val = val
        self.interval = (a, b)
        self.left = left
        self.right = right
        self.lazy = lazy if lazy else []
        self.interval_len = b - a + 1

    def __str__(self):
        return "[%2d,%2d]  val=%3d  lazy=%s" % (self.interval[0], self.interval[1], self.val, self.lazy.__str__())


def build(li: list, l: int, r: int) -> node:
    if l == r:
        return node(li[l], l, r)
    mid = l + r >> 1
    lp, rp = build(li, l, mid), build(li, mid + 1, r)
    return node(lp.val + rp.val, l, r, left=lp, right=rp)


def preOrder(root):
    if not root:
        return
    print(root)
    preOrder(root.left)
    # if root.left is None and root.right is None:
    preOrder(root.right)


def cover(li1, li2):  # 1 区间覆盖2 区间
    return li1[0] <= li2[0] <= li2[1] <= li1[1]


def has_common(li1, li2):  # 1和2有公共元素
    return not (li1[0] <= li1[1] < li2[0] <= li2[1] or li2[0] <= li2[1] < li1[0] <= li1[1])


def change(root, op, interval, val):
    if cover(interval, root.interval):
        root.lazy.append((op, val))
        if root.interval_len == 1:
            while root.lazy:
                a, b = root.lazy.pop()
                if a == 1:
                    root.val *= b
                else:
                    root.val += b * root.interval_len
        return root

    if root.left and has_common(interval, root.left.interval):
        root.left = change(root.left, op, interval, val)
    if root.right and has_common(interval, root.right.interval):
        root.right = change(root.right, op, interval, val)
    return root


def pushdown(root):  # 如果还有子节点,那么下传,否则就到叶子结点为止
    if root.left and root.right:
        root.left.lazy += copy.deepcopy(root.lazy)
        root.right.lazy += copy.deepcopy(root.lazy)
    while root.lazy:
        a, b = root.lazy.pop(0)
        if a == 1:
            root.val *= b
        else:
            root.val += b * root.interval_len
    return root, root.val


def update(root):  # 有时候,查询节点A时,A不带lazy标记,但是A的子节点带有标记,
    # 那么是否就要整个更新A子树?
    if root is None:
        return None
    if root.lazy and root.left and root.right:
        root.left.lazy += copy.deepcopy(root.lazy)
        root.right.lazy += copy.deepcopy(root.lazy)
    while root.lazy:
        a, b = root.lazy.pop(0)
        if a == 1:
            root.val *= b
        else:
            root.val += b * root.interval_len
    root.left = update(root.left)
    root.right = update(root.right)
    if root.left:
        root.val = 0
        root.val += root.left.val
        root.val += root.right.val
    return root


def query(root, interval):  # 询问区间interval
    if cover(interval, root.interval):
        root = update(root)
        return root, root.val
    if root.lazy:
        root, res = pushdown(root)
    ans = 0
    # print(root)
    if root.left and has_common(root.left.interval, interval):
        root.left, temp = query(root.left, interval)
        ans += temp
    if root.right and has_common(root.right.interval, interval):
        root.right, temp = query(root.right, interval)
        ans += temp
    # print(root.left, root.right)
    root.val = root.left.val + root.right.val
    return root, ans


li = list(map(int, input().split()))
root = build(li, 0, len(li) - 1)
for i in range(m):
    t = list(map(int, input().split()))
    if t[0] == 3:
        root, ans = query(root, [t[1] - 1, t[2] - 1])
        print(ans % p)
    else:
        root = change(root, t[0], [t[1] - 1, t[2] - 1], t[3])
    preOrder(root)

# root = update(root)
# inOrder(root)

2022/7/30 18:01
加载中...