@@ -100,32 +100,210 @@ tags:
100
100
101
101
<!-- solution:start -->
102
102
103
- ### 方法一
103
+ ### 方法一:枚举 + 数学
104
+
105
+ 我们注意到,题目中数组的长度 $n \leq 1500$,因此,我们可以枚举所有的子数组。对于每个子数组,计算其 GCD 分数,找出最大值即为答案。
106
+
107
+ 由于每个数最多只能翻倍一次,那么子数组的 GCD 最多也只能乘以 $2$,因此,我们需要统计子数组中每个数的因子 $2$ 的个数的最小值,以及这个最小值的出现次数。如果次数大于 $k$,则 GCD 分数为 GCD,否则 GCD 分数为 GCD 乘以 $2$。
108
+
109
+ 因此,我们可以预处理每个数的因子 $2$ 的个数,然后在枚举子数组时,维护当前子数组的 GCD、最小因子 $2$ 的个数以及其出现次数即可。
110
+
111
+ 时间复杂度 $O(n^2 \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 是数组 $\textit{nums}$ 的长度。
104
112
105
113
<!-- tabs:start -->
106
114
107
115
#### Python3
108
116
109
117
``` python
110
-
118
+ class Solution :
119
+ def maxGCDScore (self , nums : List[int ], k : int ) -> int :
120
+ n = len (nums)
121
+ cnt = [0 ] * n
122
+ for i, x in enumerate (nums):
123
+ while x % 2 == 0 :
124
+ cnt[i] += 1
125
+ x //= 2
126
+ ans = 0
127
+ for l in range (n):
128
+ g = 0
129
+ mi = inf
130
+ t = 0
131
+ for r in range (l, n):
132
+ g = gcd(g, nums[r])
133
+ if cnt[r] < mi:
134
+ mi = cnt[r]
135
+ t = 1
136
+ elif cnt[r] == mi:
137
+ t += 1
138
+ ans = max (ans, (g if t > k else g * 2 ) * (r - l + 1 ))
139
+ return ans
111
140
```
112
141
113
142
#### Java
114
143
115
144
``` java
116
-
145
+ class Solution {
146
+ public long maxGCDScore (int [] nums , int k ) {
147
+ int n = nums. length;
148
+ int [] cnt = new int [n];
149
+ for (int i = 0 ; i < n; ++ i) {
150
+ for (int x = nums[i]; x % 2 == 0 ; x /= 2 ) {
151
+ ++ cnt[i];
152
+ }
153
+ }
154
+ long ans = 0 ;
155
+ for (int l = 0 ; l < n; ++ l) {
156
+ int g = 0 ;
157
+ int mi = 1 << 30 ;
158
+ int t = 0 ;
159
+ for (int r = l; r < n; ++ r) {
160
+ g = gcd(g, nums[r]);
161
+ if (cnt[r] < mi) {
162
+ mi = cnt[r];
163
+ t = 1 ;
164
+ } else if (cnt[r] == mi) {
165
+ ++ t;
166
+ }
167
+ ans = Math . max(ans, (r - l + 1L ) * (t > k ? g : g * 2 ));
168
+ }
169
+ }
170
+ return ans;
171
+ }
172
+
173
+ private int gcd (int a , int b ) {
174
+ return b == 0 ? a : gcd(b, a % b);
175
+ }
176
+ }
117
177
```
118
178
119
179
#### C++
120
180
121
181
``` cpp
122
-
182
+ class Solution {
183
+ public:
184
+ long long maxGCDScore(vector<int >& nums, int k) {
185
+ int n = nums.size();
186
+ vector<int > cnt(n);
187
+ for (int i = 0; i < n; ++i) {
188
+ for (int x = nums[ i] ; x % 2 == 0; x /= 2) {
189
+ ++cnt[ i] ;
190
+ }
191
+ }
192
+
193
+ long long ans = 0;
194
+ for (int l = 0; l < n; ++l) {
195
+ int g = 0;
196
+ int mi = INT32_MAX;
197
+ int t = 0;
198
+ for (int r = l; r < n; ++r) {
199
+ g = gcd(g, nums[r]);
200
+ if (cnt[r] < mi) {
201
+ mi = cnt[r];
202
+ t = 1;
203
+ } else if (cnt[r] == mi) {
204
+ ++t;
205
+ }
206
+ long long score = static_cast <long long >(r - l + 1 ) * (t > k ? g : g * 2 );
207
+ ans = max(ans, score);
208
+ }
209
+ }
210
+
211
+ return ans;
212
+ }
213
+ };
123
214
```
124
215
125
216
#### Go
126
217
127
218
``` go
219
+ func maxGCDScore (nums []int , k int ) int64 {
220
+ n := len (nums)
221
+ cnt := make ([]int , n)
222
+ for i , x := range nums {
223
+ for x%2 == 0 {
224
+ cnt[i]++
225
+ x /= 2
226
+ }
227
+ }
228
+
229
+ ans := 0
230
+ for l := 0 ; l < n; l++ {
231
+ g := 0
232
+ mi := math.MaxInt32
233
+ t := 0
234
+ for r := l; r < n; r++ {
235
+ g = gcd (g, nums[r])
236
+ if cnt[r] < mi {
237
+ mi = cnt[r]
238
+ t = 1
239
+ } else if cnt[r] == mi {
240
+ t++
241
+ }
242
+ length := r - l + 1
243
+ score := g * length
244
+ if t <= k {
245
+ score *= 2
246
+ }
247
+ ans = max (ans, score)
248
+ }
249
+ }
250
+
251
+ return int64 (ans)
252
+ }
253
+
254
+ func gcd (a , b int ) int {
255
+ for b != 0 {
256
+ a, b = b, a%b
257
+ }
258
+ return a
259
+ }
260
+ ```
128
261
262
+ #### TypeScript
263
+
264
+ ``` ts
265
+ function maxGCDScore(nums : number [], k : number ): number {
266
+ const n = nums .length ;
267
+ const cnt: number [] = Array (n ).fill (0 );
268
+
269
+ for (let i = 0 ; i < n ; ++ i ) {
270
+ let x = nums [i ];
271
+ while (x % 2 === 0 ) {
272
+ cnt [i ]++ ;
273
+ x /= 2 ;
274
+ }
275
+ }
276
+
277
+ let ans = 0 ;
278
+ for (let l = 0 ; l < n ; ++ l ) {
279
+ let g = 0 ;
280
+ let mi = Number .MAX_SAFE_INTEGER;
281
+ let t = 0 ;
282
+ for (let r = l ; r < n ; ++ r ) {
283
+ g = gcd (g , nums [r ]);
284
+ if (cnt [r ] < mi ) {
285
+ mi = cnt [r ];
286
+ t = 1 ;
287
+ } else if (cnt [r ] === mi ) {
288
+ t ++ ;
289
+ }
290
+ const len = r - l + 1 ;
291
+ const score = (t > k ? g : g * 2 ) * len ;
292
+ ans = Math .max (ans , score );
293
+ }
294
+ }
295
+
296
+ return ans ;
297
+ }
298
+
299
+ function gcd(a : number , b : number ): number {
300
+ while (b !== 0 ) {
301
+ const temp = b ;
302
+ b = a % b ;
303
+ a = temp ;
304
+ }
305
+ return a ;
306
+ }
129
307
```
130
308
131
309
<!-- tabs:end -->
0 commit comments