@@ -88,32 +88,321 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3100-3199/3187.Pe
88
88
89
89
<!-- solution:start -->
90
90
91
- ### 方法一
91
+ ### 方法一:树状数组
92
+
93
+ 根据题目描述,对于 $0 < i < n - 1$,如果满足 $nums[ i - 1] < nums[ i] $ 且 $nums[ i] > nums[ i + 1] $,我们可以将 $nums[ i] $ 视为 $1$,否则视为 $0$。这样,对于操作 $1$,即查询子数组 $nums[ l..r] $ 中的峰值元素个数,相当于查询区间 $[ l + 1, r - 1] $ 中 $1$ 的个数。我们可以使用树状数组来维护区间 $[ 1, n - 1] $ 中 $1$ 的个数。
94
+
95
+ 而对于操作 $1$,即把 $nums[ idx] $ 更新为 $val$,只会影响到 $idx - 1$、$idx$、$idx + 1$ 这三个位置的值,因此我们只需要更新这三个位置即可。具体地,我们可以先把这三个位置的峰值元素去掉,然后更新 $nums[ idx] $ 的值,最后再把这三个位置的峰值元素加回来。
96
+
97
+ 时间复杂度 $O((n + q) \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 和 $q$ 分别是数组 ` nums ` 的长度和查询数组 ` queries ` 的长度。
92
98
93
99
<!-- tabs:start -->
94
100
95
101
#### Python3
96
102
97
103
``` python
98
-
104
+ class BinaryIndexedTree :
105
+ __slots__ = " n" , " c"
106
+
107
+ def __init__ (self , n : int ):
108
+ self .n = n
109
+ self .c = [0 ] * (n + 1 )
110
+
111
+ def update (self , x : int , delta : int ) -> None :
112
+ while x <= self .n:
113
+ self .c[x] += delta
114
+ x += x & - x
115
+
116
+ def query (self , x : int ) -> int :
117
+ s = 0
118
+ while x:
119
+ s += self .c[x]
120
+ x -= x & - x
121
+ return s
122
+
123
+
124
+ class Solution :
125
+ def countOfPeaks (self , nums : List[int ], queries : List[List[int ]]) -> List[int ]:
126
+ def update (i : int , val : int ):
127
+ if i <= 0 or i >= n - 1 :
128
+ return
129
+ if nums[i - 1 ] < nums[i] and nums[i] > nums[i + 1 ]:
130
+ tree.update(i, val)
131
+
132
+ n = len (nums)
133
+ tree = BinaryIndexedTree(n - 1 )
134
+ for i in range (1 , n - 1 ):
135
+ update(i, 1 )
136
+ ans = []
137
+ for q in queries:
138
+ if q[0 ] == 1 :
139
+ l, r = q[1 ] + 1 , q[2 ] - 1
140
+ ans.append(0 if l > r else tree.query(r) - tree.query(l - 1 ))
141
+ else :
142
+ idx, val = q[1 :]
143
+ for i in range (idx - 1 , idx + 2 ):
144
+ update(i, - 1 )
145
+ nums[idx] = val
146
+ for i in range (idx - 1 , idx + 2 ):
147
+ update(i, 1 )
148
+ return ans
99
149
```
100
150
101
151
#### Java
102
152
103
153
``` java
104
-
154
+ class BinaryIndexedTree {
155
+ private int n;
156
+ private int [] c;
157
+
158
+ public BinaryIndexedTree (int n ) {
159
+ this . n = n;
160
+ this . c = new int [n + 1 ];
161
+ }
162
+
163
+ public void update (int x , int delta ) {
164
+ for (; x <= n; x += x & - x) {
165
+ c[x] += delta;
166
+ }
167
+ }
168
+
169
+ public int query (int x ) {
170
+ int s = 0 ;
171
+ for (; x > 0 ; x -= x & - x) {
172
+ s += c[x];
173
+ }
174
+ return s;
175
+ }
176
+ }
177
+
178
+ class Solution {
179
+ private BinaryIndexedTree tree;
180
+ private int [] nums;
181
+
182
+ public List<Integer > countOfPeaks (int [] nums , int [][] queries ) {
183
+ int n = nums. length;
184
+ this . nums = nums;
185
+ tree = new BinaryIndexedTree (n - 1 );
186
+ for (int i = 1 ; i < n - 1 ; ++ i) {
187
+ update(i, 1 );
188
+ }
189
+ List<Integer > ans = new ArrayList<> ();
190
+ for (var q : queries) {
191
+ if (q[0 ] == 1 ) {
192
+ int l = q[1 ] + 1 , r = q[2 ] - 1 ;
193
+ ans. add(l > r ? 0 : tree. query(r) - tree. query(l - 1 ));
194
+ } else {
195
+ int idx = q[1 ], val = q[2 ];
196
+ for (int i = idx - 1 ; i <= idx + 1 ; ++ i) {
197
+ update(i, - 1 );
198
+ }
199
+ nums[idx] = val;
200
+ for (int i = idx - 1 ; i <= idx + 1 ; ++ i) {
201
+ update(i, 1 );
202
+ }
203
+ }
204
+ }
205
+ return ans;
206
+ }
207
+
208
+ private void update (int i , int val ) {
209
+ if (i <= 0 || i >= nums. length - 1 ) {
210
+ return ;
211
+ }
212
+ if (nums[i - 1 ] < nums[i] && nums[i] > nums[i + 1 ]) {
213
+ tree. update(i, val);
214
+ }
215
+ }
216
+ }
105
217
```
106
218
107
219
#### C++
108
220
109
221
``` cpp
110
-
222
+ class BinaryIndexedTree {
223
+ private:
224
+ int n;
225
+ vector<int > c;
226
+
227
+ public:
228
+ BinaryIndexedTree(int n)
229
+ : n(n)
230
+ , c(n + 1) {}
231
+
232
+ void update(int x, int delta) {
233
+ for (; x <= n; x += x & -x) {
234
+ c[x] += delta;
235
+ }
236
+ }
237
+
238
+ int query (int x) {
239
+ int s = 0;
240
+ for (; x > 0; x -= x & -x) {
241
+ s += c[ x] ;
242
+ }
243
+ return s;
244
+ }
245
+ };
246
+
247
+ class Solution {
248
+ public:
249
+ vector<int > countOfPeaks(vector<int >& nums, vector<vector<int >>& queries) {
250
+ int n = nums.size();
251
+ BinaryIndexedTree tree(n - 1);
252
+ auto update = [ &] (int i, int val) {
253
+ if (i <= 0 || i >= n - 1) {
254
+ return;
255
+ }
256
+ if (nums[ i - 1] < nums[ i] && nums[ i] > nums[ i + 1] ) {
257
+ tree.update(i, val);
258
+ }
259
+ };
260
+ for (int i = 1; i < n - 1; ++i) {
261
+ update(i, 1);
262
+ }
263
+ vector<int > ans;
264
+ for (auto& q : queries) {
265
+ if (q[ 0] == 1) {
266
+ int l = q[ 1] + 1, r = q[ 2] - 1;
267
+ ans.push_back(l > r ? 0 : tree.query(r) - tree.query(l - 1));
268
+ } else {
269
+ int idx = q[ 1] , val = q[ 2] ;
270
+ for (int i = idx - 1; i <= idx + 1; ++i) {
271
+ update(i, -1);
272
+ }
273
+ nums[ idx] = val;
274
+ for (int i = idx - 1; i <= idx + 1; ++i) {
275
+ update(i, 1);
276
+ }
277
+ }
278
+ }
279
+ return ans;
280
+ }
281
+ };
111
282
```
112
283
113
284
#### Go
114
285
115
286
```go
287
+ type BinaryIndexedTree struct {
288
+ n int
289
+ c []int
290
+ }
291
+
292
+ func NewBinaryIndexedTree(n int) *BinaryIndexedTree {
293
+ return &BinaryIndexedTree{n: n, c: make([]int, n+1)}
294
+ }
295
+
296
+ func (bit *BinaryIndexedTree) update(x, delta int) {
297
+ for ; x <= bit.n; x += x & -x {
298
+ bit.c[x] += delta
299
+ }
300
+ }
301
+
302
+ func (bit *BinaryIndexedTree) query(x int) int {
303
+ s := 0
304
+ for ; x > 0; x -= x & -x {
305
+ s += bit.c[x]
306
+ }
307
+ return s
308
+ }
309
+
310
+ func countOfPeaks(nums []int, queries [][]int) (ans []int) {
311
+ n := len(nums)
312
+ tree := NewBinaryIndexedTree(n - 1)
313
+ update := func(i, val int) {
314
+ if i <= 0 || i >= n-1 {
315
+ return
316
+ }
317
+ if nums[i-1] < nums[i] && nums[i] > nums[i+1] {
318
+ tree.update(i, val)
319
+ }
320
+ }
321
+ for i := 1; i < n-1; i++ {
322
+ update(i, 1)
323
+ }
324
+ for _, q := range queries {
325
+ if q[0] == 1 {
326
+ l, r := q[1]+1, q[2]-1
327
+ t := 0
328
+ if l <= r {
329
+ t = tree.query(r) - tree.query(l-1)
330
+ }
331
+ ans = append(ans, t)
332
+ } else {
333
+ idx, val := q[1], q[2]
334
+ for i := idx - 1; i <= idx+1; i++ {
335
+ update(i, -1)
336
+ }
337
+ nums[idx] = val
338
+ for i := idx - 1; i <= idx+1; i++ {
339
+ update(i, 1)
340
+ }
341
+ }
342
+ }
343
+ return
344
+ }
345
+ ```
116
346
347
+ #### TypeScript
348
+
349
+ ``` ts
350
+ class BinaryIndexedTree {
351
+ private n: number ;
352
+ private c: number [];
353
+
354
+ constructor (n : number ) {
355
+ this .n = n ;
356
+ this .c = Array (n + 1 ).fill (0 );
357
+ }
358
+
359
+ update(x : number , delta : number ): void {
360
+ for (; x <= this .n ; x += x & - x ) {
361
+ this .c [x ] += delta ;
362
+ }
363
+ }
364
+
365
+ query(x : number ): number {
366
+ let s = 0 ;
367
+ for (; x > 0 ; x -= x & - x ) {
368
+ s += this .c [x ];
369
+ }
370
+ return s ;
371
+ }
372
+ }
373
+
374
+ function countOfPeaks(nums : number [], queries : number [][]): number [] {
375
+ const n = nums .length ;
376
+ const tree = new BinaryIndexedTree (n - 1 );
377
+ const update = (i : number , val : number ): void => {
378
+ if (i <= 0 || i >= n - 1 ) {
379
+ return ;
380
+ }
381
+ if (nums [i - 1 ] < nums [i ] && nums [i ] > nums [i + 1 ]) {
382
+ tree .update (i , val );
383
+ }
384
+ };
385
+ for (let i = 1 ; i < n - 1 ; ++ i ) {
386
+ update (i , 1 );
387
+ }
388
+ const ans: number [] = [];
389
+ for (const q of queries ) {
390
+ if (q [0 ] === 1 ) {
391
+ const [l, r] = [q [1 ] + 1 , q [2 ] - 1 ];
392
+ ans .push (l > r ? 0 : tree .query (r ) - tree .query (l - 1 ));
393
+ } else {
394
+ const [idx, val] = [q [1 ], q [2 ]];
395
+ for (let i = idx - 1 ; i <= idx + 1 ; ++ i ) {
396
+ update (i , - 1 );
397
+ }
398
+ nums [idx ] = val ;
399
+ for (let i = idx - 1 ; i <= idx + 1 ; ++ i ) {
400
+ update (i , 1 );
401
+ }
402
+ }
403
+ }
404
+ return ans ;
405
+ }
117
406
```
118
407
119
408
<!-- tabs:end -->
0 commit comments