@@ -100,32 +100,210 @@ tags:
100100
101101<!-- solution:start -->
102102
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}$ 的长度。
104112
105113<!-- tabs:start -->
106114
107115#### Python3
108116
109117``` 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
111140```
112141
113142#### Java
114143
115144``` 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+ }
117177```
118178
119179#### C++
120180
121181``` 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+ };
123214```
124215
125216#### Go
126217
127218``` 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+ ```
128261
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+ }
129307```
130308
131309<!-- tabs:end -->
0 commit comments