@@ -61,7 +61,7 @@ numMatrix.sumRegion(2, 1, 4, 3); // 返回 10 (即,右侧红色矩形的和)
61
61
62
62
<!-- 这里可写通用的实现逻辑 -->
63
63
64
- 树状数组。
64
+ ** 方法一: 树状数组**
65
65
66
66
树状数组,也称作“二叉索引树”(Binary Indexed Tree)或 Fenwick 树。 它可以高效地实现如下两个操作:
67
67
@@ -72,6 +72,8 @@ numMatrix.sumRegion(2, 1, 4, 3); // 返回 10 (即,右侧红色矩形的和)
72
72
73
73
对于本题,可以构建二维树状数组。
74
74
75
+ ** 方法二:线段树**
76
+
75
77
<!-- tabs:start -->
76
78
77
79
### ** Python3**
@@ -121,6 +123,74 @@ class NumMatrix:
121
123
return sum (tree.query(col2 + 1 ) - tree.query(col1) for tree in self .trees[row1: row2 + 1 ])
122
124
123
125
126
+ # Your NumMatrix object will be instantiated and called as such:
127
+ # obj = NumMatrix(matrix)
128
+ # obj.update(row,col,val)
129
+ # param_2 = obj.sumRegion(row1,col1,row2,col2)
130
+ ```
131
+
132
+ ``` python
133
+ class Node :
134
+ def __init__ (self ):
135
+ self .l = 0
136
+ self .r = 0
137
+ self .v = 0
138
+
139
+ class SegmentTree :
140
+ def __init__ (self , nums ):
141
+ n = len (nums)
142
+ self .tr = [Node() for _ in range (4 * n)]
143
+ self .build(1 , 1 , n)
144
+ for i, v in enumerate (nums):
145
+ self .modify(1 , i + 1 , v)
146
+
147
+ def build (self , u , l , r ):
148
+ self .tr[u].l = l
149
+ self .tr[u].r = r
150
+ if l == r:
151
+ return
152
+ mid = (l + r) >> 1
153
+ self .build(u << 1 , l, mid)
154
+ self .build(u << 1 | 1 , mid + 1 , r)
155
+
156
+ def modify (self , u , x , v ):
157
+ if self .tr[u].l == x and self .tr[u].r == x:
158
+ self .tr[u].v = v
159
+ return
160
+ mid = (self .tr[u].l + self .tr[u].r) >> 1
161
+ if x <= mid:
162
+ self .modify(u << 1 , x, v)
163
+ else :
164
+ self .modify(u << 1 | 1 , x, v)
165
+ self .pushup(u)
166
+
167
+ def pushup (self , u ):
168
+ self .tr[u].v = self .tr[u << 1 ].v + self .tr[u << 1 | 1 ].v
169
+
170
+ def query (self , u , l , r ):
171
+ if self .tr[u].l >= l and self .tr[u].r <= r:
172
+ return self .tr[u].v
173
+ mid = (self .tr[u].l + self .tr[u].r) >> 1
174
+ v = 0
175
+ if l <= mid:
176
+ v = self .query(u << 1 , l, r)
177
+ if r > mid:
178
+ v += self .query(u << 1 | 1 , l, r)
179
+ return v
180
+
181
+ class NumMatrix :
182
+
183
+ def __init__ (self , matrix : List[List[int ]]):
184
+ self .trees = [SegmentTree(row) for row in matrix]
185
+
186
+ def update (self , row : int , col : int , val : int ) -> None :
187
+ tree = self .trees[row]
188
+ tree.modify(1 , col + 1 , val)
189
+
190
+ def sumRegion (self , row1 : int , col1 : int , row2 : int , col2 : int ) -> int :
191
+ return sum (self .trees[row].query(1 , col1 + 1 , col2 + 1 ) for row in range (row1, row2 + 1 ))
192
+
193
+
124
194
# Your NumMatrix object will be instantiated and called as such:
125
195
# obj = NumMatrix(matrix)
126
196
# obj.update(row,col,val)
@@ -202,6 +272,107 @@ class NumMatrix {
202
272
*/
203
273
```
204
274
275
+ ``` java
276
+ class Node {
277
+ int l;
278
+ int r;
279
+ int v;
280
+ }
281
+
282
+ class SegmentTree {
283
+ private Node [] tr;
284
+
285
+ public SegmentTree (int [] nums ) {
286
+ int n = nums. length;
287
+ tr = new Node [4 * n];
288
+ for (int i = 0 ; i < tr. length; ++ i) {
289
+ tr[i] = new Node ();
290
+ }
291
+ build(1 , 1 , n);
292
+ for (int i = 0 ; i < n; ++ i) {
293
+ modify(1 , i + 1 , nums[i]);
294
+ }
295
+ }
296
+
297
+ public void build (int u , int l , int r ) {
298
+ tr[u]. l = l;
299
+ tr[u]. r = r;
300
+ if (l == r) {
301
+ return ;
302
+ }
303
+ int mid = (l + r) >> 1 ;
304
+ build(u << 1 , l, mid);
305
+ build(u << 1 | 1 , mid + 1 , r);
306
+ }
307
+
308
+ public void modify (int u , int x , int v ) {
309
+ if (tr[u]. l == x && tr[u]. r == x) {
310
+ tr[u]. v = v;
311
+ return ;
312
+ }
313
+ int mid = (tr[u]. l + tr[u]. r) >> 1 ;
314
+ if (x <= mid) {
315
+ modify(u << 1 , x, v);
316
+ } else {
317
+ modify(u << 1 | 1 , x, v);
318
+ }
319
+ pushup(u);
320
+ }
321
+
322
+ public void pushup (int u ) {
323
+ tr[u]. v = tr[u << 1 ]. v + tr[u << 1 | 1 ]. v;
324
+ }
325
+
326
+ public int query (int u , int l , int r ) {
327
+ if (tr[u]. l >= l && tr[u]. r <= r) {
328
+ return tr[u]. v;
329
+ }
330
+ int mid = (tr[u]. l + tr[u]. r) >> 1 ;
331
+ int v = 0 ;
332
+ if (l <= mid) {
333
+ v = query(u << 1 , l, r);
334
+ }
335
+ if (r > mid) {
336
+ v += query(u << 1 | 1 , l, r);
337
+ }
338
+ return v;
339
+ }
340
+ }
341
+
342
+ class NumMatrix {
343
+ private SegmentTree [] trees;
344
+
345
+ public NumMatrix (int [][] matrix ) {
346
+ int m = matrix. length;
347
+ trees = new SegmentTree [m];
348
+ for (int i = 0 ; i < m; ++ i) {
349
+ trees[i] = new SegmentTree (matrix[i]);
350
+ }
351
+ }
352
+
353
+ public void update (int row , int col , int val ) {
354
+ SegmentTree tree = trees[row];
355
+ tree. modify(1 , col + 1 , val);
356
+ }
357
+
358
+ public int sumRegion (int row1 , int col1 , int row2 , int col2 ) {
359
+ int s = 0 ;
360
+ for (int row = row1; row <= row2; ++ row) {
361
+ SegmentTree tree = trees[row];
362
+ s += tree. query(1 , col1 + 1 , col2 + 1 );
363
+ }
364
+ return s;
365
+ }
366
+ }
367
+
368
+ /**
369
+ * Your NumMatrix object will be instantiated and called as such:
370
+ * NumMatrix obj = new NumMatrix(matrix);
371
+ * obj.update(row,col,val);
372
+ * int param_2 = obj.sumRegion(row1,col1,row2,col2);
373
+ */
374
+ ```
375
+
205
376
### ** C++**
206
377
207
378
``` cpp
@@ -275,6 +446,91 @@ public:
275
446
* /
276
447
```
277
448
449
+ ```cpp
450
+ class Node {
451
+ public:
452
+ int l;
453
+ int r;
454
+ int v;
455
+ };
456
+
457
+ class SegmentTree {
458
+ public:
459
+ vector<Node*> tr;
460
+
461
+ SegmentTree(vector<int>& nums) {
462
+ int n = nums.size();
463
+ tr.resize(4 * n);
464
+ for (int i = 0; i < tr.size(); ++i) tr[i] = new Node();
465
+ build(1, 1, n);
466
+ for (int i = 0; i < n; ++i) modify(1, i + 1, nums[i]);
467
+ }
468
+
469
+ void build(int u, int l, int r) {
470
+ tr[u]->l = l;
471
+ tr[u]->r = r;
472
+ if (l == r) return;
473
+ int mid = (l + r) >> 1;
474
+ build(u << 1, l, mid);
475
+ build(u << 1 | 1, mid + 1, r);
476
+ }
477
+
478
+ void modify(int u, int x, int v) {
479
+ if (tr[u]->l == x && tr[u]->r == x)
480
+ {
481
+ tr[u]->v = v;
482
+ return;
483
+ }
484
+ int mid = (tr[u]->l + tr[u]->r) >> 1;
485
+ if (x <= mid) modify(u << 1, x, v);
486
+ else modify(u << 1 | 1, x, v);
487
+ pushup(u);
488
+ }
489
+
490
+ void pushup(int u) {
491
+ tr[u]->v = tr[u << 1]->v + tr[u << 1 | 1]->v;
492
+ }
493
+
494
+ int query(int u, int l, int r) {
495
+ if (tr[u]->l >= l && tr[u]->r <= r) return tr[u]->v;
496
+ int mid = (tr[u]->l + tr[u]->r) >> 1;
497
+ int v = 0;
498
+ if (l <= mid) v = query(u << 1, l, r);
499
+ if (r > mid) v += query(u << 1 | 1, l, r);
500
+ return v;
501
+ }
502
+ };
503
+
504
+ class NumMatrix {
505
+ public:
506
+ vector<SegmentTree*> trees;
507
+
508
+ NumMatrix(vector<vector<int>>& matrix) {
509
+ int m = matrix.size();
510
+ trees.resize(m);
511
+ for (int i = 0; i < m; ++i) trees[i] = new SegmentTree(matrix[i]);
512
+ }
513
+
514
+ void update(int row, int col, int val) {
515
+ SegmentTree* tree = trees[row];
516
+ tree->modify(1, col + 1, val);
517
+ }
518
+
519
+ int sumRegion(int row1, int col1, int row2, int col2) {
520
+ int s = 0;
521
+ for (int row = row1; row <= row2; ++row) s += trees[row]->query(1, col1 + 1, col2 + 1);
522
+ return s;
523
+ }
524
+ };
525
+
526
+ /**
527
+ * Your NumMatrix object will be instantiated and called as such:
528
+ * NumMatrix* obj = new NumMatrix(matrix);
529
+ * obj->update(row,col,val);
530
+ * int param_2 = obj->sumRegion(row1,col1,row2,col2);
531
+ */
532
+ ```
533
+
278
534
### ** Go**
279
535
280
536
``` go
0 commit comments