@@ -55,22 +55,250 @@ numArray.sumRange(0, 2); // 返回 8 ,sum([1,2,5]) = 8
55
55
56
56
<!-- 这里可写通用的实现逻辑 -->
57
57
58
+ 树状数组。
59
+
60
+ 树状数组,也称作“二叉索引树”(Binary Indexed Tree)或 Fenwick 树。 它可以高效地实现如下两个操作:
61
+
62
+ 1 . ** 单点更新** ` update(x, delta) ` : 把序列 x 位置的数加上一个值 delta;
63
+ 1 . ** 前缀和查询** ` query(x) ` :查询序列 ` [1,...x] ` 区间的区间和,即位置 x 的前缀和。
64
+
65
+ 这两个操作的时间复杂度均为 ` O(log n) ` 。
66
+
58
67
<!-- tabs:start -->
59
68
60
69
### ** Python3**
61
70
62
71
<!-- 这里可写当前语言的特殊实现逻辑 -->
63
72
64
73
``` python
74
+ class BinaryIndexedTree :
75
+ def __init__ (self , n ):
76
+ self .n = n
77
+ self .c = [0 ] * (n + 1 )
78
+
79
+ @ staticmethod
80
+ def lowbit (x ):
81
+ return x & - x
82
+
83
+ def update (self , x , delta ):
84
+ while x <= self .n:
85
+ self .c[x] += delta
86
+ x += BinaryIndexedTree.lowbit(x)
87
+
88
+ def query (self , x ):
89
+ s = 0
90
+ while x > 0 :
91
+ s += self .c[x]
92
+ x -= BinaryIndexedTree.lowbit(x)
93
+ return s
94
+
95
+ class NumArray :
96
+
97
+ def __init__ (self , nums : List[int ]):
98
+ self .tree = BinaryIndexedTree(len (nums))
99
+ for i, v in enumerate (nums, 1 ):
100
+ self .tree.update(i, v)
101
+
102
+ def update (self , index : int , val : int ) -> None :
103
+ prev = self .sumRange(index, index)
104
+ self .tree.update(index + 1 , val - prev)
105
+
106
+ def sumRange (self , left : int , right : int ) -> int :
107
+ return self .tree.query(right + 1 ) - self .tree.query(left)
65
108
109
+
110
+ # Your NumArray object will be instantiated and called as such:
111
+ # obj = NumArray(nums)
112
+ # obj.update(index,val)
113
+ # param_2 = obj.sumRange(left,right)
66
114
```
67
115
68
116
### ** Java**
69
117
70
118
<!-- 这里可写当前语言的特殊实现逻辑 -->
71
119
72
120
``` java
121
+ class BinaryIndexedTree {
122
+ private int n;
123
+ private int [] c;
124
+
125
+ public BinaryIndexedTree (int n ) {
126
+ this . n = n;
127
+ c = new int [n + 1 ];
128
+ }
129
+
130
+ public void update (int x , int delta ) {
131
+ while (x <= n) {
132
+ c[x] += delta;
133
+ x += lowbit(x);
134
+ }
135
+ }
136
+
137
+ public int query (int x ) {
138
+ int s = 0 ;
139
+ while (x > 0 ) {
140
+ s += c[x];
141
+ x -= lowbit(x);
142
+ }
143
+ return s;
144
+ }
145
+
146
+ public static int lowbit (int x ) {
147
+ return x & - x;
148
+ }
149
+ }
150
+
151
+ class NumArray {
152
+ private BinaryIndexedTree tree;
153
+
154
+ public NumArray (int [] nums ) {
155
+ int n = nums. length;
156
+ tree = new BinaryIndexedTree (n);
157
+ for (int i = 0 ; i < n; ++ i) {
158
+ tree. update(i + 1 , nums[i]);
159
+ }
160
+ }
161
+
162
+ public void update (int index , int val ) {
163
+ int prev = sumRange(index, index);
164
+ tree. update(index + 1 , val - prev);
165
+ }
166
+
167
+ public int sumRange (int left , int right ) {
168
+ return tree. query(right + 1 ) - tree. query(left);
169
+ }
170
+ }
171
+
172
+ /**
173
+ * Your NumArray object will be instantiated and called as such:
174
+ * NumArray obj = new NumArray(nums);
175
+ * obj.update(index,val);
176
+ * int param_2 = obj.sumRange(left,right);
177
+ */
178
+ ```
179
+
180
+ ### ** C++**
181
+
182
+ ``` cpp
183
+ class BinaryIndexedTree {
184
+ public:
185
+ int n;
186
+ vector<int > c;
187
+
188
+ BinaryIndexedTree(int _n): n(_n), c(_n + 1){}
189
+
190
+ void update (int x, int delta) {
191
+ while (x <= n)
192
+ {
193
+ c[ x] += delta;
194
+ x += lowbit(x);
195
+ }
196
+ }
197
+
198
+ int query(int x) {
199
+ int s = 0;
200
+ while (x > 0)
201
+ {
202
+ s += c[x];
203
+ x -= lowbit(x);
204
+ }
205
+ return s;
206
+ }
207
+
208
+ int lowbit(int x) {
209
+ return x & -x;
210
+ }
211
+ };
212
+
213
+
214
+ class NumArray {
215
+ public:
216
+ BinaryIndexedTree* tree;
217
+
218
+ NumArray(vector<int>& nums) {
219
+ int n = nums.size();
220
+ tree = new BinaryIndexedTree(n);
221
+ for (int i = 0; i < n; ++i) tree->update(i + 1, nums[i]);
222
+ }
223
+
224
+ void update(int index, int val) {
225
+ int prev = sumRange(index, index);
226
+ tree->update(index + 1, val - prev);
227
+ }
228
+
229
+ int sumRange(int left, int right) {
230
+ return tree->query(right + 1) - tree->query(left);
231
+ }
232
+ };
233
+
234
+ /**
235
+ * Your NumArray object will be instantiated and called as such:
236
+ * NumArray* obj = new NumArray(nums);
237
+ * obj->update(index,val);
238
+ * int param_2 = obj->sumRange(left,right);
239
+ * /
240
+ ```
241
+
242
+ ### **Go**
243
+
244
+ ```go
245
+ type BinaryIndexedTree struct {
246
+ n int
247
+ c []int
248
+ }
249
+
250
+ func newBinaryIndexedTree(n int) *BinaryIndexedTree {
251
+ c := make([]int, n+1)
252
+ return &BinaryIndexedTree{n, c}
253
+ }
254
+
255
+ func (this *BinaryIndexedTree) lowbit(x int) int {
256
+ return x & -x
257
+ }
258
+
259
+ func (this *BinaryIndexedTree) update(x, delta int) {
260
+ for x <= this.n {
261
+ this.c[x] += delta
262
+ x += this.lowbit(x)
263
+ }
264
+ }
265
+
266
+ func (this *BinaryIndexedTree) query(x int) int {
267
+ s := 0
268
+ for x > 0 {
269
+ s += this.c[x]
270
+ x -= this.lowbit(x)
271
+ }
272
+ return s
273
+ }
274
+
275
+ type NumArray struct {
276
+ tree *BinaryIndexedTree
277
+ }
278
+
279
+ func Constructor(nums []int) NumArray {
280
+ tree := newBinaryIndexedTree(len(nums))
281
+ for i, v := range nums {
282
+ tree.update(i+1, v)
283
+ }
284
+ return NumArray{tree}
285
+ }
286
+
287
+ func (this *NumArray) Update(index int, val int) {
288
+ prev := this.SumRange(index, index)
289
+ this.tree.update(index+1, val-prev)
290
+ }
291
+
292
+ func (this *NumArray) SumRange(left int, right int) int {
293
+ return this.tree.query(right+1) - this.tree.query(left)
294
+ }
73
295
296
+ /**
297
+ * Your NumArray object will be instantiated and called as such:
298
+ * obj := Constructor(nums);
299
+ * obj.Update(index,val);
300
+ * param_2 := obj.SumRange(left,right);
301
+ */
74
302
```
75
303
76
304
### ** ...**
0 commit comments