@@ -68,22 +68,314 @@ The amount of new area painted on day 1 is 0.
68
68
69
69
<!-- 这里可写通用的实现逻辑 -->
70
70
71
+ ** 方法一:线段树**
72
+
73
+ 线段树将整个区间分割为多个不连续的子区间,子区间的数量不超过 ` log(width) ` 。更新某个元素的值,只需要更新 ` log(width) ` 个区间,并且这些区间都包含在一个包含该元素的大区间内。区间修改时,需要使用** 懒标记** 保证效率。
74
+
75
+ - 线段树的每个节点代表一个区间;
76
+ - 线段树具有唯一的根节点,代表的区间是整个统计范围,如 ` [1, N] ` ;
77
+ - 线段树的每个叶子节点代表一个长度为 1 的元区间 ` [x, x] ` ;
78
+ - 对于每个内部节点 ` [l, r] ` ,它的左儿子是 ` [l, mid] ` ,右儿子是 ` [mid + 1, r] ` , 其中 ` mid = ⌊(l + r) / 2⌋ ` (即向下取整)。
79
+
80
+ 对于本题,线段树节点维护的信息有:
81
+
82
+ 1 . 区间中元素大于 0 的个数 v
83
+ 1 . 懒标记 add
84
+
71
85
<!-- tabs:start -->
72
86
73
87
### ** Python3**
74
88
75
89
<!-- 这里可写当前语言的特殊实现逻辑 -->
76
90
77
91
``` python
92
+ class Node :
93
+ def __init__ (self , l , r ):
94
+ self .left = None
95
+ self .right = None
96
+ self .l = l
97
+ self .r = r
98
+ self .mid = (l + r) >> 1
99
+ self .v = 0
100
+ self .add = 0
101
+
102
+
103
+ class SegmentTree :
104
+ def __init__ (self ):
105
+ self .root = Node(1 , 10 ** 5 + 10 )
106
+
107
+ def modify (self , l , r , v , node = None ):
108
+ if l > r:
109
+ return
110
+ if node is None :
111
+ node = self .root
112
+ if node.l >= l and node.r <= r:
113
+ node.v = node.r - node.l + 1
114
+ node.add = v
115
+ return
116
+ self .pushdown(node)
117
+ if l <= node.mid:
118
+ self .modify(l, r, v, node.left)
119
+ if r > node.mid:
120
+ self .modify(l, r, v, node.right)
121
+ self .pushup(node)
122
+
123
+ def query (self , l , r , node = None ):
124
+ if l > r:
125
+ return 0
126
+ if node is None :
127
+ node = self .root
128
+ if node.l >= l and node.r <= r:
129
+ return node.v
130
+ self .pushdown(node)
131
+ v = 0
132
+ if l <= node.mid:
133
+ v += self .query(l, r, node.left)
134
+ if r > node.mid:
135
+ v += self .query(l, r, node.right)
136
+ return v
78
137
138
+ def pushup (self , node ):
139
+ node.v = node.left.v + node.right.v
140
+
141
+ def pushdown (self , node ):
142
+ if node.left is None :
143
+ node.left = Node(node.l, node.mid)
144
+ if node.right is None :
145
+ node.right = Node(node.mid + 1 , node.r)
146
+ if node.add:
147
+ left, right = node.left, node.right
148
+ left.v = left.r - left.l + 1
149
+ right.v = right.r - right.l + 1
150
+ left.add = node.add
151
+ right.add = node.add
152
+ node.add = 0
153
+
154
+
155
+ class Solution :
156
+ def amountPainted (self , paint : List[List[int ]]) -> List[int ]:
157
+ tree = SegmentTree()
158
+ ans = []
159
+ for i, (start, end) in enumerate (paint):
160
+ l, r = start + 1 , end
161
+ v = tree.query(l, r)
162
+ ans.append(r - l + 1 - v)
163
+ tree.modify(l, r, 1 )
164
+ return ans
79
165
```
80
166
81
167
### ** Java**
82
168
83
169
<!-- 这里可写当前语言的特殊实现逻辑 -->
84
170
85
171
``` java
172
+ class Node {
173
+ Node left;
174
+ Node right;
175
+ int l;
176
+ int r;
177
+ int mid;
178
+ int v;
179
+ int add;
180
+
181
+ public Node (int l , int r ) {
182
+ this . l = l;
183
+ this . r = r;
184
+ this . mid = (l + r) >> 1 ;
185
+ }
186
+ }
187
+
188
+ class SegmentTree {
189
+ private Node root = new Node (1 , 100010 );
190
+
191
+ public SegmentTree () {
192
+
193
+ }
194
+
195
+ public void modify (int l , int r , int v ) {
196
+ modify(l, r, v, root);
197
+ }
198
+
199
+ public void modify (int l , int r , int v , Node node ) {
200
+ if (l > r) {
201
+ return ;
202
+ }
203
+ if (node. l >= l && node. r <= r) {
204
+ node. v = node. r - node. l + 1 ;
205
+ node. add = v;
206
+ return ;
207
+ }
208
+ pushdown(node);
209
+ if (l <= node. mid) {
210
+ modify(l, r, v, node. left);
211
+ }
212
+ if (r > node. mid) {
213
+ modify(l, r, v, node. right);
214
+ }
215
+ pushup(node);
216
+ }
217
+
218
+ public int query (int l , int r ) {
219
+ return query(l, r, root);
220
+ }
221
+
222
+ public int query (int l , int r , Node node ) {
223
+ if (l > r) {
224
+ return 0 ;
225
+ }
226
+ if (node. l >= l && node. r <= r) {
227
+ return node. v;
228
+ }
229
+ pushdown(node);
230
+ int v = 0 ;
231
+ if (l <= node. mid) {
232
+ v += query(l, r, node. left);
233
+ }
234
+ if (r > node. mid) {
235
+ v += query(l, r, node. right);
236
+ }
237
+ return v;
238
+ }
239
+
240
+ public void pushup (Node node ) {
241
+ node. v = node. left. v + node. right. v;
242
+ }
243
+
244
+ public void pushdown (Node node ) {
245
+ if (node. left == null ) {
246
+ node. left = new Node (node. l, node. mid);
247
+ }
248
+ if (node. right == null ) {
249
+ node. right = new Node (node. mid + 1 , node. r);
250
+ }
251
+ if (node. add != 0 ) {
252
+ Node left = node. left, right = node. right;
253
+ left. add = node. add;
254
+ right. add = node. add;
255
+ left. v = left. r - left. l + 1 ;
256
+ right. v = right. r - right. l + 1 ;
257
+ node. add = 0 ;
258
+ }
259
+ }
260
+ }
261
+
262
+ class Solution {
263
+ public int [] amountPainted (int [][] paint ) {
264
+ SegmentTree tree = new SegmentTree ();
265
+ int n = paint. length;
266
+ int [] ans = new int [n];
267
+ for (int i = 0 ; i < n; ++ i) {
268
+ int l = paint[i][0 ] + 1 ;
269
+ int r = paint[i][1 ];
270
+ int v = tree. query(l, r);
271
+ ans[i] = r - l + 1 - v;
272
+ tree. modify(l, r, 1 );
273
+ }
274
+ return ans;
275
+ }
276
+ }
277
+ ```
278
+
279
+ ### ** C++**
280
+
281
+ ``` cpp
282
+ class Node {
283
+ public:
284
+ Node* left;
285
+ Node* right;
286
+ int l;
287
+ int r;
288
+ int mid;
289
+ int v;
290
+ int add;
291
+
292
+ Node(int l, int r) {
293
+ this->l = l;
294
+ this->r = r;
295
+ this->mid = (l + r) >> 1;
296
+ this->left = this->right = nullptr;
297
+ v = add = 0;
298
+ }
299
+ };
300
+
301
+ class SegmentTree {
302
+ private:
303
+ Node* root;
304
+
305
+ public:
306
+ SegmentTree() {
307
+ root = new Node(1, 100010);
308
+ }
309
+
310
+ void modify(int l, int r, int v) {
311
+ modify(l, r, v, root);
312
+ }
313
+
314
+ void modify (int l, int r,int v, Node* node) {
315
+ if (l > r) return;
316
+ if (node->l >= l && node->r <= r)
317
+ {
318
+ node->v = node->r - node->l + 1;
319
+ node->add = v;
320
+ return;
321
+ }
322
+ pushdown(node);
323
+ if (l <= node->mid) modify(l, r, v, node->left);
324
+ if (r > node->mid) modify(l, r, v, node->right);
325
+ pushup(node);
326
+ }
327
+
328
+ int query(int l, int r) {
329
+ return query(l, r, root);
330
+ }
331
+
332
+ int query(int l, int r, Node* node) {
333
+ if (l > r) return 0;
334
+ if (node->l >= l && node-> r <= r) return node->v;
335
+ pushdown(node);
336
+ int v = 0;
337
+ if (l <= node->mid) v += query(l, r, node->left);
338
+ if (r > node->mid) v += query(l, r, node->right);
339
+ return v;
340
+ }
341
+
342
+ void pushup(Node* node) {
343
+ node->v = node->left->v + node->right->v;
344
+ }
345
+
346
+ void pushdown(Node* node) {
347
+ if (!node->left) node->left = new Node(node->l, node->mid);
348
+ if (!node->right) node->right = new Node(node->mid + 1, node->r);
349
+ if (node->add)
350
+ {
351
+ Node* left = node->left;
352
+ Node* right = node->right;
353
+ left->v = left->r - left->l + 1;
354
+ right->v = right->r - right->l + 1;
355
+ left->add = node->add;
356
+ right->add = node->add;
357
+ node->add = 0;
358
+ }
359
+ }
360
+ };
86
361
362
+ class Solution {
363
+ public:
364
+ vector<int > amountPainted(vector<vector<int >>& paint) {
365
+ int n = paint.size();
366
+ vector<int > ans(n);
367
+ SegmentTree* tree = new SegmentTree();
368
+ for (int i = 0; i < n; ++i)
369
+ {
370
+ int l = paint[ i] [ 0 ] + 1;
371
+ int r = paint[ i] [ 1 ] ;
372
+ int v = tree->query(l, r);
373
+ ans[ i] = r - l + 1 - v;
374
+ tree->modify(l, r, 1);
375
+ }
376
+ return ans;
377
+ }
378
+ };
87
379
```
88
380
89
381
### **TypeScript**
0 commit comments