Input: nums =[2,1,4,4,4,2], k =2Output: 48Explanation: We take the subarray [4,4,4], the gcd-sum of this array is4*(4+4+4)=48.It can be shown that we can not select any other subarray with a gcd-sum greater than 48.
Example 2:
1
2
3
4
Input: nums =[7,3,9,4], k =1Output: 81Explanation: We take the subarray [9], the gcd-sum of this array is9*9=81.It can be shown that we can not select any other subarray with a gcd-sum greater than 81.
The main idea is that for each possible GCD value, we can check all subarrays where every element is divisible by that GCD, and try to maximize the sum of such subarrays of length at least k. Since the GCD of a subarray must divide all its elements, we can enumerate all possible divisors for each element and use a sliding window to find the best sum for each divisor.
For each unique value in nums, enumerate all its divisors and map each divisor to the indices where it appears.
For each divisor d, collect all indices where nums[i] is divisible by d.
For each contiguous segment of such indices, use a sliding window of size at least k to find the maximum sum of a subarray where all elements are divisible by d.
For each such sum, compute gcd-sum as sum * d and keep track of the maximum.
classSolution {
public:int maxGcdSum(vector<int>& nums, int k) {
int n = nums.size(), ans =0;
unordered_map<int, vector<int>> divs;
for (int i =0; i < n; ++i) {
for (int d =1; d * d <= nums[i]; ++d) {
if (nums[i] % d ==0) {
divs[d].push_back(i);
if (d != nums[i] / d) divs[nums[i]/d].push_back(i);
}
}
}
for (auto& [d, idxs] : divs) {
int m = idxs.size();
vector<longlong> psum(m+1);
for (int i =0; i < m; ++i) psum[i+1] = psum[i] + nums[idxs[i]];
for (int i =0; i + k <= m; ++i) {
ans = max(ans, (int)((psum[i+k] - psum[i]) * d));
}
}
return ans;
}
};
classSolution {
publicintmaxGcdSum(int[] nums, int k) {
int n = nums.length, ans = 0;
Map<Integer, List<Integer>> divs =new HashMap<>();
for (int i = 0; i < n; ++i) {
for (int d = 1; d * d <= nums[i]; ++d) {
if (nums[i]% d == 0) {
divs.computeIfAbsent(d, z ->new ArrayList<>()).add(i);
if (d != nums[i]/ d) divs.computeIfAbsent(nums[i]/d, z ->new ArrayList<>()).add(i);
}
}
}
for (var e : divs.entrySet()) {
int d = e.getKey();
List<Integer> idxs = e.getValue();
int m = idxs.size();
int[] psum =newint[m+1];
for (int i = 0; i < m; ++i) psum[i+1]= psum[i]+ nums[idxs.get(i)];
for (int i = 0; i + k <= m; ++i) {
ans = Math.max(ans, (psum[i+k]- psum[i]) * d);
}
}
return ans;
}
}
classSolution {
funmaxGcdSum(nums: IntArray, k: Int): Int {
val n = nums.size
var ans = 0val divs = mutableMapOf<Int, MutableList<Int>>()
for (i in0 until n) {
var d = 1while (d * d <= nums[i]) {
if (nums[i] % d ==0) {
divs.getOrPut(d) { mutableListOf() }.add(i)
if (d != nums[i] / d) divs.getOrPut(nums[i]/d) { mutableListOf() }.add(i)
}
d++ }
}
for ((d, idxs) in divs) {
val m = idxs.size
val psum = IntArray(m+1)
for (i in0 until m) psum[i+1] = psum[i] + nums[idxs[i]]
for (i in0..m-k) {
ans = maxOf(ans, (psum[i+k] - psum[i]) * d)
}
}
return ans
}
}
classSolution:
defmaxGcdSum(self, nums: list[int], k: int) -> int:
from collections import defaultdict
n = len(nums)
ans =0 divs: dict[int, list[int]] = defaultdict(list)
for i, v in enumerate(nums):
d =1while d * d <= v:
if v % d ==0:
divs[d].append(i)
if d != v // d:
divs[v//d].append(i)
d +=1for d, idxs in divs.items():
m = len(idxs)
psum = [0] * (m+1)
for i in range(m):
psum[i+1] = psum[i] + nums[idxs[i]]
for i in range(m-k+1):
ans = max(ans, (psum[i+k] - psum[i]) * d)
return ans
impl Solution {
pubfnmax_gcd_sum(nums: Vec<i32>, k: i32) -> i32 {
use std::collections::HashMap;
let n = nums.len();
letmut ans =0;
letmut divs: HashMap<i32, Vec<usize>>= HashMap::new();
for (i, &v) in nums.iter().enumerate() {
letmut d =1;
while d * d <= v {
if v % d ==0 {
divs.entry(d).or_default().push(i);
if d != v / d {
divs.entry(v/d).or_default().push(i);
}
}
d +=1;
}
}
for (d, idxs) in divs.iter() {
let m = idxs.len();
letmut psum =vec![0; m+1];
for i in0..m {
psum[i+1] = psum[i] + nums[idxs[i]];
}
for i in0..=m-k asusize {
ans = ans.max((psum[i+k asusize] - psum[i]) **d);
}
}
ans
}
}
⏰ Time complexity: O(n * sqrt(maxA)), where n is the length of nums and maxA is the maximum value in nums. For each element, we enumerate its divisors (up to sqrt(maxA)), and for each divisor, we process its index list.
🧺 Space complexity: O(n * sqrt(maxA)), for storing the mapping from divisors to indices.