ps = [0] + list(accumulate(b))
Sigma = lambda i,j : ps[j+1] - ps[i]
N = 100<<10
bit_length = [0] * N
for i in range(1,N):
bit_length[i] = bit_length[i>>1] + 1
class ST:
def __init__(self,A,func=max):
dp = A[:]
self.st = st = [dp]
self.func = func
j, N = 1, len(dp)
while 2*j<=N:
dp = [func(dp[i],dp[i+j]) for i in range(N-2*j+1)]
st.append(dp)
j <<= 1
def query(self,l,r):
j = bit_length[r-l+1]-1
return self.func(self.st[j][l],self.st[j][r-(1<<j)+1])
b1 = BIT(n,0,inf,min)
class BIT:
def __init__(self,n, postfix, default_val, reduce_op, sizeQ = 10**5):
self.N = n + 2
self.postfix = postfix
self.default_val = default_val
self.reduce_op = reduce_op
self.A = [default_val] * self.N if n < sizeQ*n.bit_length() \
else defaultdict(lambda:default_val)
def add(self,i,x):
i = i+1 if not self.postfix else self.N-(i+1)
if i <=0 : i = 1
while i < self.N:
self.A[i] = self.reduce_op(self.A[i],x)
i += -i & i
def get(self,i):
i = i+1 if not self.postfix else self.N-(i+1)
if i >= self.N : i = self.N - 1
res = self.default_val
while i > 0:
res = self.reduce_op(res,self.A[i])
i ^= -i & i
return res
class SEGMENTTREE:
def __init__(self, n):
n += 2
self.N = 1 << (n-1).bit_length()
self.n = n
self.default_val = default_val = 0 ########
self.A = [default_val for _ in range(n + self.N) ]
self.reduce_op = max #####
# def reduce_op(self,a,b): #####
def _set(self,i,x): #######
self.A[i] = max(x,self.A[i])
def build(self,_A):
l = self.N
r = self.N + len(_A)-1
for i,x in enumerate(_A,l):
self._set(i,x)
while l > 1:
l >>= 1
r >>= 1
for i in range(l,r+1):
self.A[i] = self.reduce_op(self.A[i<<1],self.A[i<<1|1])
def set(self,i,x):
i += self.N
self._set(i,x)
while i > 1:
i >>= 1
self.A[i] = self.reduce_op(self.A[i<<1],self.A[i<<1|1])
def get(self,i) : return self.A[l + self.N]
def queryAll(self) : return self.A[1]
def query(self,l,r ):
l = max(0,l) + self.N
r = min(self.n-1,r) + self.N
res = self.default_val
while l <= r :
if l & 1 == 1: res = self.reduce_op(self.A[l],res)
if r & 1 == 0: res = self.reduce_op(res, self.A[r])
l = l + 1 >> 1
r = r - 1 >> 1
return res
区间0-1翻转 求1个数
tree = LAZY_SEGMENTTREE(
defaultval = 0 ,
defaultlazy = 0 ,
left = 0, right = n,
reduce_op = lambda val1,val2: val1 + val2,
lazy_op = lambda lazy0,lz : lazy0 ^ lz,
lazy_val = lambda l,r,lz,val0: (r-l+1)-val0 if lz else val0
)
区间赋值
tree = LAZY_SEGMENTTREE(
defaultval = 0 ,
defaultlazy = inf ,
left = 0, right = 10**9,
reduce_op = lambda val1,val2: val1 + val2,
lazy_op = lambda lazy0,lz : lz,
lazy_val = lambda l,r,lz,val0: lz*(r-l+1) if lz != inf else val0
)
区间增加
tree = LAZY_SEGMENTTREE(
defaultval = 0 ,
defaultlazy = 0 ,
left = 0, right = 10**9,
reduce_op = lambda val1,val2: val1 + val2,
lazy_op = lambda lazy0,lz : lazy0 + lz,
lazy_val = lambda l,r,lz,val0: val0+lz*(r-l+1)
)
区间最大值
tree = LAZY_SEGMENTTREE(
defaultval = 0 ,
defaultlazy = 0 ,
left= 0, right = max(nums),
reduce_op = lambda val1,val2: val1 if val1 > val2 else val2,
lazy_op = lambda lazy0,lz : lazy0 if lazy0 > lz else lz,
lazy_val = lambda l,r,lz,val0: lz if lz > val0 else val0
)
class LAZY_SEGMENTTREE:
def __init__(self,
defaultval = 0 ,
defaultlazy = 0 ,
left = 0, right = 10**9,
reduce_op = lambda val1,val2: val1 + val2,
lazy_op = lambda lazy0,lz : lazy0 + lz,
lazy_val = lambda l,r,lz,val0: val0+lz*(r-l+1)
):
self.defaultval = defaultval
self.defaultlazy = defaultlazy
self.left = left
self.right = right
self.reduce_op = reduce_op
self.lazy_op = lazy_op
self.lazy_val = lazy_val
self.val = defaultdict(lambda:defaultval)
self.lazy = defaultdict(lambda:defaultlazy)
def lazy_do(self,i,l,r,lz):
self.val[i] = self.lazy_val(l,r,lz,self.val[i])
self.lazy[i] = self.lazy_op(self.lazy[i],lz)
def update(self,start,end,lz):
return self._update(start,end,self.left,self.right,lz,1)
def query(self,start,end):
return self._query(start,end,self.left,self.right,1)
def _down(self, i, l , r):
mid = (l + r) // 2
if self.lazy[i] != self.defaultlazy :
self.lazy_do(i*2,l, mid,self.lazy[i])
self.lazy_do(i*2+1,mid + 1, r,self.lazy[i])
self.lazy[i] = self.defaultlazy
return mid
def _update(self, start, end, l, r, lz, i ):
if start <= l and r <= end:
self.lazy_do(i,l,r,lz)
else:
mid = self._down(i, l , r)
if mid >= start : self._update(start, end, l, mid, lz, i * 2,)
if mid+1 <= end : self._update(start, end, mid + 1, r, lz, i * 2 + 1)
self.val[i] = self.reduce_op(self.val[i*2] , self.val[i*2+1])
def _query(self,start, end, l, r, i):
if start <= l and r <= end: return self.val[i]
else:
mid = self._down( i, l , r)
res = self.defaultval
if mid >= start : res = self.reduce_op(self._query(start, end, l, mid, i * 2),res )
if mid+1 <= end : res = self.reduce_op(res,self._query(start, end, mid + 1, r, i * 2 + 1) )
return res
def build(self, A, i=0 ,l=0 ,r=-1 ):
if l == r: self.val[i] = A[l]
elif r==-1:
self.left,self.right = 0,len(A)-1
self.build(A,1,0,len(A)-1)
else :
mid = (l+r) // 2
self.build(A, i*2,l,mid)
self.build(A, i*2+1,mid+1,r)
self.val[i] = self.reduce_op(self.val[i*2],self.val[i*2+1])