Skip to content

Commit e99c7ce

Browse files
author
robot
committed
线段树
1 parent 446b4a5 commit e99c7ce

File tree

1 file changed

+83
-0
lines changed

1 file changed

+83
-0
lines changed

‎src/codeTemplates/segmentTree.js

+83
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,89 @@ export default {
109109
},
110110
],
111111
},
112+
{
113+
text: "区间和懒更新(区间更新)线段树",
114+
problems: [
115+
{
116+
id: "handling-sum-queries-after-update",
117+
title: "2569. 更新数组后处理求和查询"
118+
}
119+
],
120+
codes: [
121+
{
122+
language: "py",
123+
text: `
124+
class LazySegmentTree:
125+
def __init__(self, data):
126+
'''
127+
data:传入的数组
128+
'''
129+
self.data = data
130+
self.n = len(data)
131+
# 申请4倍data长度的空间来存线段树节点
132+
self.tree = [0] * (4 * self.n) # 索引i的左孩子索引为2i+1,右孩子为2i+2
133+
# 要点 1 开始
134+
self.dirty = [True] * (4 * self.n) # 索引i的左孩子索引为2i+1,右孩子为2i+2
135+
# 要点 1 结束
136+
if self.n:
137+
self.build(0, 0, self.n-1)
138+
139+
def build(self, tree_index, l, r):
140+
if l == r:
141+
self.tree[tree_index] = self.data[l]
142+
return
143+
left, right = 2 * tree_index + 1, 2 * tree_index + 2
144+
mid = (l + r) // 2
145+
self.build(left, l, mid)
146+
self.build(right, mid+1, r)
147+
self.tree[tree_index] = self.tree[left] + self.tree[right]
148+
149+
def updateSum(self, ql, qr):
150+
self.update(0, 0, self.n-1, ql, qr)
151+
152+
def update(self, tree_index, l, r, ql, qr):
153+
if l == ql and r == qr:
154+
# 要点 2 开始
155+
self.dirty[tree_index] = not self.dirty[tree_index]
156+
self.tree[tree_index] = r - l + 1 - self.tree[tree_index]
157+
# 要点 2 结束
158+
return
159+
left, right = 2 * tree_index + 1, 2 * tree_index + 2
160+
mid = (l + r) // 2
161+
# 要点 3 开始
162+
if not self.dirty[tree_index]: # 如果有标记就处理
163+
self.update(left, l, mid, l, mid)
164+
self.update(right, mid+1, r, mid+1, r)
165+
self.dirty[tree_index] = True # 重置回去
166+
# 要点 3 结束
167+
if qr <= mid: self.update(left, l, mid, ql, qr)
168+
elif ql > mid: self.update(right, mid+1, r, ql, qr)
169+
else:
170+
self.update(left, l, mid, ql, mid)
171+
self.update(right, mid+1, r, mid+1, qr)
172+
self.tree[tree_index] = self.tree[left] + self.tree[right]
173+
174+
def querySum(self, ql, qr):
175+
return self.query(0, 0, self.n-1, ql, qr)
176+
177+
def query(self, tree_index, l, r, ql, qr):
178+
if l == ql and r == qr:
179+
return self.tree[tree_index]
180+
left, right = 2 * tree_index + 1, 2 * tree_index + 2
181+
mid = (l + r) // 2
182+
# 要点 3 开始
183+
if not self.dirty[tree_index]: # 如果有标记就处理
184+
self.update(left, l, mid, l, mid)
185+
self.update(right, mid+1, r, mid+1, r)
186+
self.dirty[tree_index] = True # 重置回去
187+
# 要点 3 结束
188+
if qr <= mid: return self.query(left, l, mid, ql, qr)
189+
if ql > mid: return self.query(right, mid+1, r, ql, qr)
190+
return self.query(left, l, mid, ql, mid) + self.query(right, mid+1, r, mid+1, qr)
191+
`
192+
}
193+
]
194+
},
112195
{
113196
text: "计数线段树",
114197
problems: [

0 commit comments

Comments
 (0)