Given integers n and m, construct a strictly increasing sequence of m positive integers with sum exactly equal to n such that the GCD of the sequence is maximized. If multiple sequences have the same maximum GCD, return the lexicographically smallest one. If not possible, return -1.
Examples :
Input : n = 24, m = 3
Output : [4, 8, 12]
Explanation : 3, 6, 15 is also a possible sequence having gcd as 3, but 4, 8, 12 has a gcd of 4 which is maximum possible among all.Input : n = 6, m = 4
Output : [-1 ]
Explanation: It is not possible, as the smallest possible GCD sequence would be (1, 2, 3, 4), which gives a sum greater than n. Hence, the answer is -1.
Approach:
The idea is to form the sequence as
GCD × [1, 2, ..., m]and find the largest possible GCD such that the total sum doesn't exceedn. We then construct the sequence using this GCD, adjusting the last element to match the exact sum. If such a sequence isn't possible, we return-1.
Step by Step Implementations:
- Compute the minimum sum of the first
mnatural numbers: minSum= (m×(m+1))/2, if minSum > n then output will be -1. - Let
b = n / minSum. Iterate over all divisors ofnwhich is less than or equal tobto find the largest such divisorr. - Build the sequence
r × [1, 2, ..., m - 1]as the initial sequence (i.e., [r×1, r×2, r×3, r×4 ,..., r×(m-1)] - Make the last element: lastEle = n − r × (m×(m-1))/2.
- Hence the final sequence is - [r×1, r×2, r×3, r×4 ,..., r×(m-1), lastEle].
#include <iostream>
#include <vector>
using namespace std;
vector<int> maxGcdSeq(int n, int m) {
vector<int> ans;
// Minimum required sum = 1 + 2 + ... + m = m*(m+1)/2
int b = n / (m * (m + 1) / 2);
// If not enough sum to form a
// valid increasing sequence
if (b == 0) {
ans.push_back(-1);
} else {
int r = 1;
// Find the largest divisor of n that is <= b
for (int x = 1; x * x <= n; x++) {
if (n % x != 0) continue;
if (x <= b && x > r)
r = x;
if (n / x <= b && n / x > r)
r = n / x;
}
// Build the first m-1 elements: r × [1, 2, ..., m-1]
for (int i = 1; i < m; i++)
ans.push_back(r * i);
// Compute the last element to make total sum = n
int last = n - r * (m * (m - 1) / 2);
ans.push_back(last);
}
return ans;
}
int main() {
int n = 24, m = 3;
vector<int> result = maxGcdSeq(n, m);
for (auto ele : result)
cout << ele << ' ';
cout << endl;
}
import java.util.*;
class GfG {
public static int[] maxGcdSeq(int n, int m) {
int b = n / (m * (m + 1) / 2);
// If not enough sum to form a valid increasing sequence
if (b == 0) {
return new int[]{-1};
}
int r = 1;
// Find the largest divisor of n that is <= b
for (int x = 1; x * x <= n; x++) {
if (n % x != 0) continue;
if (x <= b && x > r)
r = x;
if ((n / x) <= b && (n / x) > r)
r = n / x;
}
// Create array of size m
int[] ans = new int[m];
// Fill the first m-1 elements: r × [1, 2, ..., m-1]
for (int i = 0; i < m - 1; i++) {
ans[i] = r * (i + 1);
}
// Compute the last element to make total sum = n
ans[m - 1] = n - r * (m * (m - 1) / 2);
return ans;
}
public static void main(String[] args) {
int n = 24, m = 3;
int[] result = maxGcdSeq(n, m);
for (int num : result) {
System.out.print(num + " ");
}
System.out.println();
}
}
def maxGcdSeq(n, m):
b = n // (m * (m + 1) // 2)
# If not enough sum to form a
# valid increasing sequence
if b == 0:
return [-1]
r = 1
# Find the largest divisor of n that is <= b
for x in range(1, int(n**0.5) + 1):
if n % x != 0:
continue
if x <= b and x > r:
r = x
if n // x <= b and n // x > r:
r = n // x
# Build the first m-1 elements
ans = [r * i for i in range(1, m)]
# Compute the last element to make total sum = n
last = n - r * (m * (m - 1) // 2)
ans.append(last)
return ans
if __name__ == "__main__":
n = 24
m = 3
result = maxGcdSeq(n, m)
print(*result)
using System;
using System.Collections.Generic;
class GfG {
public static int[] maxGcdSeq(int n, int m) {
int b = n / (m * (m + 1) / 2);
// If not enough sum to form a valid increasing sequence
if (b == 0)
{
return new int[] { -1 };
}
int r = 1;
// Find the largest divisor of n that is <= b
for (int x = 1; x * x <= n; x++)
{
if (n % x != 0) continue;
if (x <= b && x > r)
r = x;
if (n / x <= b && n / x > r)
r = n / x;
}
int[] result = new int[m];
// Fill the first m-1 elements: r × [1, 2, ..., m-1]
for (int i = 0; i < m - 1; i++)
{
result[i] = r * (i + 1);
}
// Compute the last element to make total sum = n
result[m - 1] = n - r * (m * (m - 1) / 2);
return result;
}
public static void Main()
{
int n = 24, m = 3;
int[] result = maxGcdSeq(n, m);
foreach (int num in result)
{
Console.Write(num + " ");
}
Console.WriteLine();
}
}
function maxGcdSeq(n, m) {
const minSum = (m * (m + 1)) / 2;
const b = Math.floor(n / minSum);
// If it's not possible to
// form a valid sequence
if (b === 0) {
return [-1];
}
let r = 1;
// Find the largest divisor of n that is <= b
for (let x = 1; x * x <= n; x++) {
if (n % x !== 0) continue;
if (x <= b && x > r) r = x;
const div = n / x;
if (div <= b && div > r) r = div;
}
const result = [];
// Add first m-1 elements:
// r * [1, 2, ..., m-1]
for (let i = 1; i < m; i++) {
result.push(r * i);
}
// Compute the last element to
// make total sum = n
const last = n - r * ((m * (m - 1)) / 2);
result.push(last);
return result;
}
// Driver Code
const n = 24, m = 3;
const res = maxGcdSeq(n, m);
console.log(res.join(' '));
Output
4 8 12
Time Complexity: O(√n + m), finding all divisors of n takes O(√n) time, and constructing the sequence takes O(m) time.
Space Complexity: O(m)