escapist404 @ 2023-07-24 21:56:19
class SegmentTree:
val = []
tag = []
child = []
root = 0
size = 0
def __new_node(self):
self.val.append(0)
self.tag.append(0)
self.child.append([0, 0])
return len(self.val) - 1
def __push_down(self, index:int, size:int):
if self.child[index][0] == 0:
self.child[index][0] = self.__new_node()
if self.child[index][1] == 0:
self.child[index][1] = self.__new_node()
self.val[self.child[index][0]] = self.apply(self.val[self.child[index][0]], self.tag[index], int(size / 2))
self.val[self.child[index][1]] = self.apply(self.val[self.child[index][1]], self.tag[index], size - int(size / 2))
self.tag[self.child[index][0]] = self.attach(self.tag[self.child[index][0]], self.tag[index])
self.tag[self.child[index][1]] = self.attach(self.tag[self.child[index][1]], self.tag[index])
self.tag[index] = self.e_tag()
def __push_up(self, index):
self.val[index] = self.opt(self.val[self.child[index][0]], self.val[self.child[index][1]])
def __set(self, _l:int, _r:int, _tag, l:int, r:int, index:int):
if l >= _r or r <= _l:
return
if _l <= l and r <= _r:
self.val[index] = self.apply(self.val[index], _tag, r - l)
self.tag[index] = self.attach(self.tag[index], _tag)
return
self.__push_down(index, r - l)
mid = int((l + r) / 2)
self.__set(_l, _r, _tag, l, mid, self.child[index][0])
self.__set(_l, _r, _tag, mid, r, self.child[index][1])
self.__push_up(index)
def __get(self, _l:int, _r:int, l:int, r:int, index:int):
if l >= _r or r <= _l:
return self.e_val()
if _l <= l and r <= _r:
return self.val[index]
self.__push_down(index, r - l)
mid = int((l + r) / 2)
if _l >= mid:
return self.__get(_l, _r, mid, r, self.child[index][1])
if _r <= mid:
return self.__get(_l, _r, l, mid, self.child[index][0])
return self.opt(self.__get(_l, _r, l, mid, self.child[index][0]), self.__get(_l, _r, mid, r, self.child[index][1]))
def setRange(self, _l:int, _r:int, _tag):
self.__set(_l, _r, _tag, 0, self.size, self.root)
def setPos(self, _pos:int, _tag):
self.__set(_pos, _pos + 1, _tag, 0, self.size, self.root)
def getRange(self, _l:int, _r:int):
return self.__get(_l, _r, 0, self.size, self.root)
def getPos(self, _pos:int):
return self.__get(_pos, _pos + 1, 0, self.size, self.root)
def getAll(self):
return self.val[self.root]
def __init__(self, n:int, opt, e_val, apply, attach, e_tag):
self.root = self.__new_node()
self.size = n
self.opt = opt
self.e_val = e_val
self.apply = apply
self.attach = attach
self.e_tag = e_tag
n, m = [int(i) for i in input().split()]
T = SegmentTree(n, lambda ls, rs : ls + rs, lambda : 0, lambda _val, _tag, _size : _val + _tag * _size, lambda _tag_old, _tag_new : _tag_old + _tag_new, lambda : 0)
a = [int(i) for i in input().split()]
for i in range(n):
T.setPos(i, a[i])
for i in range(m):
opt = [int(i) for i in input().split()]
if opt[0] == 1:
T.setRange(opt[1] - 1, opt[2], opt[3])
else:
print(T.getRange(opt[1] - 1, opt[2]))
如题,使用 python 实现了一棵线段树,但无法通过本题(#7~#10 TLE)。
初步原因猜测是 python 本身常数大,导致理论复杂度正确而无法通过。
因此求助针对这份代码的优化。doge
by fjy666 @ 2023-07-24 21:58:48
选 PyPy3