@@ -109,6 +109,89 @@ export default {
109
109
} ,
110
110
] ,
111
111
} ,
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
+ } ,
112
195
{
113
196
text : "计数线段树" ,
114
197
problems : [
0 commit comments