@@ -56,6 +56,8 @@ numArray.sumRange(0, 2); // 返回 1 + 2 + 5 = 8
56
56
57
57
<!-- 这里可写通用的实现逻辑 -->
58
58
59
+ ** 方法一:树状数组**
60
+
59
61
树状数组。
60
62
61
63
树状数组,也称作“二叉索引树”(Binary Indexed Tree)或 Fenwick 树。 它可以高效地实现如下两个操作:
@@ -65,6 +67,8 @@ numArray.sumRange(0, 2); // 返回 1 + 2 + 5 = 8
65
67
66
68
这两个操作的时间复杂度均为 ` O(log n) ` 。
67
69
70
+ ** 方法二:线段树**
71
+
68
72
<!-- tabs:start -->
69
73
70
74
### ** Python3**
@@ -108,6 +112,73 @@ class NumArray:
108
112
return self .tree.query(right + 1 ) - self .tree.query(left)
109
113
110
114
115
+ # Your NumArray object will be instantiated and called as such:
116
+ # obj = NumArray(nums)
117
+ # obj.update(index,val)
118
+ # param_2 = obj.sumRange(left,right)
119
+ ```
120
+
121
+ ``` python
122
+ class Node :
123
+ def __init__ (self ):
124
+ self .l = 0
125
+ self .r = 0
126
+ self .v = 0
127
+
128
+ class SegmentTree :
129
+ def __init__ (self , nums ):
130
+ n = len (nums)
131
+ self .tr = [Node() for _ in range (4 * n)]
132
+ self .build(1 , 1 , n)
133
+ for i, v in enumerate (nums, 1 ):
134
+ self .modify(1 , i, v)
135
+
136
+ def build (self , u , l , r ):
137
+ self .tr[u].l = l
138
+ self .tr[u].r = r
139
+ if l == r:
140
+ return
141
+ mid = (l + r) >> 1
142
+ self .build(u << 1 , l, mid)
143
+ self .build(u << 1 | 1 , mid + 1 , r)
144
+
145
+ def modify (self , u , x , v ):
146
+ if self .tr[u].l == x and self .tr[u].r == x:
147
+ self .tr[u].v = v
148
+ return
149
+ mid = (self .tr[u].l + self .tr[u].r) >> 1
150
+ if x <= mid:
151
+ self .modify(u << 1 , x, v)
152
+ else :
153
+ self .modify(u << 1 | 1 , x, v)
154
+ self .pushup(u)
155
+
156
+ def pushup (self , u ):
157
+ self .tr[u].v = self .tr[u << 1 ].v + self .tr[u << 1 | 1 ].v
158
+
159
+ def query (self , u , l , r ):
160
+ if self .tr[u].l >= l and self .tr[u].r <= r:
161
+ return self .tr[u].v
162
+ mid = (self .tr[u].l + self .tr[u].r) >> 1
163
+ v = 0
164
+ if l <= mid:
165
+ v = self .query(u << 1 , l, r)
166
+ if r > mid:
167
+ v += self .query(u << 1 | 1 , l, r)
168
+ return v
169
+
170
+ class NumArray :
171
+
172
+ def __init__ (self , nums : List[int ]):
173
+ self .tree = SegmentTree(nums)
174
+
175
+ def update (self , index : int , val : int ) -> None :
176
+ self .tree.modify(1 , index + 1 , val)
177
+
178
+ def sumRange (self , left : int , right : int ) -> int :
179
+ return self .tree.query(1 , left + 1 , right + 1 )
180
+
181
+
111
182
# Your NumArray object will be instantiated and called as such:
112
183
# obj = NumArray(nums)
113
184
# obj.update(index,val)
@@ -178,6 +249,97 @@ class NumArray {
178
249
*/
179
250
```
180
251
252
+ ``` java
253
+ class Node {
254
+ int l;
255
+ int r;
256
+ int v;
257
+ }
258
+
259
+ class SegmentTree {
260
+ private Node [] tr;
261
+
262
+ public SegmentTree (int [] nums ) {
263
+ int n = nums. length;
264
+ tr = new Node [4 * n];
265
+ for (int i = 0 ; i < tr. length; ++ i) {
266
+ tr[i] = new Node ();
267
+ }
268
+ build(1 , 1 , n);
269
+ for (int i = 0 ; i < n; ++ i) {
270
+ modify(1 , i + 1 , nums[i]);
271
+ }
272
+ }
273
+
274
+ public void build (int u , int l , int r ) {
275
+ tr[u]. l = l;
276
+ tr[u]. r = r;
277
+ if (l == r) {
278
+ return ;
279
+ }
280
+ int mid = (l + r) >> 1 ;
281
+ build(u << 1 , l, mid);
282
+ build(u << 1 | 1 , mid + 1 , r);
283
+ }
284
+
285
+ public void modify (int u , int x , int v ) {
286
+ if (tr[u]. l == x && tr[u]. r == x) {
287
+ tr[u]. v = v;
288
+ return ;
289
+ }
290
+ int mid = (tr[u]. l + tr[u]. r) >> 1 ;
291
+ if (x <= mid) {
292
+ modify(u << 1 , x, v);
293
+ } else {
294
+ modify(u << 1 | 1 , x, v);
295
+ }
296
+ pushup(u);
297
+ }
298
+
299
+ public void pushup (int u ) {
300
+ tr[u]. v = tr[u << 1 ]. v + tr[u << 1 | 1 ]. v;
301
+ }
302
+
303
+ public int query (int u , int l , int r ) {
304
+ if (tr[u]. l >= l && tr[u]. r <= r) {
305
+ return tr[u]. v;
306
+ }
307
+ int mid = (tr[u]. l + tr[u]. r) >> 1 ;
308
+ int v = 0 ;
309
+ if (l <= mid) {
310
+ v = query(u << 1 , l, r);
311
+ }
312
+ if (r > mid) {
313
+ v += query(u << 1 | 1 , l, r);
314
+ }
315
+ return v;
316
+ }
317
+ }
318
+
319
+ class NumArray {
320
+ private SegmentTree tree;
321
+
322
+ public NumArray (int [] nums ) {
323
+ tree = new SegmentTree (nums);
324
+ }
325
+
326
+ public void update (int index , int val ) {
327
+ tree. modify(1 , index + 1 , val);
328
+ }
329
+
330
+ public int sumRange (int left , int right ) {
331
+ return tree. query(1 , left + 1 , right + 1 );
332
+ }
333
+ }
334
+
335
+ /**
336
+ * Your NumArray object will be instantiated and called as such:
337
+ * NumArray obj = new NumArray(nums);
338
+ * obj.update(index,val);
339
+ * int param_2 = obj.sumRange(left,right);
340
+ */
341
+ ```
342
+
181
343
### ** C++**
182
344
183
345
``` cpp
@@ -240,6 +402,86 @@ public:
240
402
* /
241
403
```
242
404
405
+ ```cpp
406
+ class Node {
407
+ public:
408
+ int l;
409
+ int r;
410
+ int v;
411
+ };
412
+
413
+ class SegmentTree {
414
+ public:
415
+ vector<Node*> tr;
416
+
417
+ SegmentTree(vector<int>& nums) {
418
+ int n = nums.size();
419
+ tr.resize(4 * n);
420
+ for (int i = 0; i < tr.size(); ++i) tr[i] = new Node();
421
+ build(1, 1, n);
422
+ for (int i = 0; i < n; ++i) modify(1, i + 1, nums[i]);
423
+ }
424
+
425
+ void build(int u, int l, int r) {
426
+ tr[u]->l = l;
427
+ tr[u]->r = r;
428
+ if (l == r) return;
429
+ int mid = (l + r) >> 1;
430
+ build(u << 1, l, mid);
431
+ build(u << 1 | 1, mid + 1, r);
432
+ }
433
+
434
+ void modify(int u, int x, int v) {
435
+ if (tr[u]->l == x && tr[u]->r == x)
436
+ {
437
+ tr[u]->v = v;
438
+ return;
439
+ }
440
+ int mid = (tr[u]->l + tr[u]->r) >> 1;
441
+ if (x <= mid) modify(u << 1, x, v);
442
+ else modify(u << 1 | 1, x, v);
443
+ pushup(u);
444
+ }
445
+
446
+ void pushup(int u) {
447
+ tr[u]->v = tr[u << 1]->v + tr[u << 1 | 1]->v;
448
+ }
449
+
450
+ int query(int u, int l, int r) {
451
+ if (tr[u]->l >= l && tr[u]->r <= r) return tr[u]->v;
452
+ int mid = (tr[u]->l + tr[u]->r) >> 1;
453
+ int v = 0;
454
+ if (l <= mid) v = query(u << 1, l, r);
455
+ if (r > mid) v += query(u << 1 | 1, l, r);
456
+ return v;
457
+ }
458
+ };
459
+
460
+ class NumArray {
461
+ public:
462
+ SegmentTree* tree;
463
+
464
+ NumArray(vector<int>& nums) {
465
+ tree = new SegmentTree(nums);
466
+ }
467
+
468
+ void update(int index, int val) {
469
+ return tree->modify(1, index + 1, val);
470
+ }
471
+
472
+ int sumRange(int left, int right) {
473
+ return tree->query(1, left + 1, right + 1);
474
+ }
475
+ };
476
+
477
+ /**
478
+ * Your NumArray object will be instantiated and called as such:
479
+ * NumArray* obj = new NumArray(nums);
480
+ * obj->update(index,val);
481
+ * int param_2 = obj->sumRange(left,right);
482
+ */
483
+ ```
484
+
243
485
### ** Go**
244
486
245
487
``` go
0 commit comments