蓝桥20054 银河纪元:lazy线段树


查询结果和1,-1的出现顺序无关,只与个数有关,此处省略严格证明(我也没证)
查询的时候要统计整个区间中的1,-1数量,修改是修改区间,所以用lazy线段树

import os
import sys

# 请在此输入您的代码
# 1 和 -1 的顺序似乎并不会影响结果,所以只要知道有多少 1 和 -1 就可以了。
# 修改操作,需要知道[l, r]中的1, -1 数量。还是计算区间和就够了,用n和区间和t[1]就能计算1,-1的数量
n = int(input())
nums = list(map(int, input().split()))

class Seg:
    def __init__(self, n, A):
        self.n = n 
        self.t = [0] * 4 * n
        self.f = [0] * 4 * n
        self.A = A
        self.build()
    
    def up(self, a, b):
        return a + b 
    
    def do(self, o, l, r, x):
        self.t[o] = -self.t[o]
        self.f[o] = x - self.f[o]
    
    def build(self,o=1,l=0,r=None):
        r = self.n-1 if r is None else r
        if l==r:
            self.t[o] = self.A[l]
            return
        m = (l+r)//2
        self.build(o*2,l,m)
        self.build(o*2+1,m+1,r)
        self.t[o] = self.up(self.t[o*2],self.t[o*2+1])

    def down(self,o,l,m,r):
        if self.f[o] != self.f[0]:
            self.do(o*2,l,m,self.f[o])
            self.do(o*2+1,m+1,r,self.f[o])
            self.f[o] = self.f[0]

    def update(self,a,b,x,o=1,l=0,r=None):
        r = self.n-1 if r is None else r
        if a<=l and r<=b:
            self.do(o,l,r,x)
            return
        m = (l+r)//2
        self.down(o,l,m,r)
        if a<=m:
            self.update(a,b,x,o*2,l,m)
        if m<b:
            self.update(a,b,x,o*2+1,m+1,r)
        self.t[o] = self.up(self.t[o*2],self.t[o*2+1])

tree = Seg(n, nums)
t = int(input())
for _ in range(t):
    op, x, y = map(int, input().split())
    if op == 1:
        tree.update(x - 1, y - 1, 1)
    else:
        s = tree.t[1]
        ones = (s + n) // 2
        _ones = n - ones
        ones = ones - y if ones > y else 0
        _ones = _ones - x if _ones > x else 0
        print(max(ones, _ones))
posted @ 2025-03-11 15:48  凉叶染香  阅读(9)  评论(0)    收藏  举报