Open In App

Find element that maximizes LCM of an Array in the range 1 to M

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Share
Report issue
Report

Given an array arr of size N containing numbers in the range [1, M], the task is to find an element, in the range [1, M], which maximises the LCM.
Examples: 
 

Input: arr[]={3, 4, 2, 7}, M = 8 
Output:
Explanation: 
The LCM of existing array (3, 4, 2, 7) = 84 
Adding the remaining numbers in 1 to 8 and check the corresponding LCM of the resulting array. 
1: LCM of(1, 3, 4, 2, 7) is 84 
5: LCM of(5, 3, 4, 2, 7) is 420 
6: LCM of(6, 3, 4, 2, 7) is 84 
8: LCM of(5, 3, 4, 2, 7) is 168 
Clearly, adding 5 maximizes the LCM.
Input: arr[]={2, 5, 3, 8, 1}, M = 9 
Output:
 

 

Naive Approach: 
 

  • Calculate the LCM of the given array.
  • Calculate the LCM after adding each element in the range [1, M] not present in the array and return the element for which it is maximum.

Efficient Approach: 
 

  • Precompute the prime factors, of numbers till 1000, using Sieve.
  • Store the frequency of every prime factor of the LCM of the given array.
  • Iterate from values [1, M] and for every value not present in the array, calculate the product of differences in the frequencies of prime factors of that number and that of the LCM of the given array.
  • Return the element which provides the maximum product.

Below code is the implementation of the above approach:
 

C++




// C++ program to find the element
// to be added to maximize the LCM
 
#include <bits/stdc++.h>
using namespace std;
 
// Vector which stores the prime factors
// of all the numbers upto 10000
vector<int> primeFactors[10001];
set<int> s;
 
// Function which finds prime
// factors using sieve method
void findPrimeFactors()
{
 
    // Boolean array which stores
    // true if the index is prime
    bool primes[10001];
    memset(primes, true, sizeof(primes));
 
    // Sieve of Eratosthenes
    for (int i = 2; i < 10001; i++) {
 
        if (primes[i]) {
            for (int j = i; j < 10001; j += i) {
 
                if (j != i) {
                    primes[j] = false;
                }
                primeFactors[j].push_back(i);
            }
        }
    }
}
 
// Function which stores frequency of every
// prime factor of LCM of the initial array
void primeFactorsofLCM(int* frequecyOfPrimes,
                       int* arr, int n)
{
 
    for (int i = 0; i < n; i++) {
        for (auto a : primeFactors[arr[i]]) {
 
            int k = 0;
 
            // While the prime factor
            // divides the number
            while ((arr[i] % a) == 0) {
                arr[i] /= a;
                k++;
            }
 
            frequecyOfPrimes[a]
                = max(frequecyOfPrimes[a], k);
        }
    }
}
 
// Function which returns the element
// which should be added to array
int elementToBeAdded(int* frequecyOfPrimes, int m)
{
    int product = 1;
 
    // To store the final answer
    int ans = 1;
 
    for (int i = 2; i <= m; i++) {
 
        if (s.find(i) != s.end())
            continue;
 
        int j = i;
        int current = 1;
 
        for (auto a : primeFactors[j]) {
 
            int k = 0;
 
            // While the prime factor
            // divides the number
            while ((j % a) == 0) {
 
                j /= a;
                k++;
                if (k > frequecyOfPrimes[a]) {
                    current *= a;
                }
            }
        }
 
        // Check element which provides
        // the maximum product
        if (current > product) {
            product = current;
            ans = i;
        }
    }
    return ans;
}
 
void findElement(int* arr, int n, int m)
{
 
    for (int i = 0; i < n; i++)
        s.insert(arr[i]);
    int frequencyOfPrimes[10001] = { 0 };
    primeFactorsofLCM(frequencyOfPrimes, arr, n);
    cout << elementToBeAdded(frequencyOfPrimes, m)
         << endl;
}
 
// Driver code
int main()
{
    // Precomputing the prime factors
    // of all numbers upto 10000
    findPrimeFactors();
 
    int N = 5;
    int M = 9;
    int arr[] = { 2, 5, 3, 8, 1 };
 
    findElement(arr, N, M);
 
    return 0;
}


Java




// Java program to find the element
// to be added to maximize the LCM
import java.util.*;
 
class GFG{
 
// Vector which stores the prime factors
// of all the numbers upto 10000
static Vector<Integer> []primeFactors = new Vector[10001];
static HashSet<Integer> s = new HashSet<Integer>();
 
// Function which finds prime
// factors using sieve method
static void findPrimeFactors()
{
 
    // Boolean array which stores
    // true if the index is prime
    boolean []primes = new boolean[10001];
    Arrays.fill(primes, true);
 
    // Sieve of Eratosthenes
    for (int i = 2; i < 10001; i++) {
 
        if (primes[i]) {
            for (int j = i; j < 10001; j += i) {
 
                if (j != i) {
                    primes[j] = false;
                }
                primeFactors[j].add(i);
            }
        }
    }
}
 
// Function which stores frequency of every
// prime factor of LCM of the initial array
static void primeFactorsofLCM(int []frequecyOfPrimes,
                    int[] arr, int n)
{
 
    for (int i = 0; i < n; i++) {
        for (int a : primeFactors[arr[i]]) {
 
            int k = 0;
 
            // While the prime factor
            // divides the number
            while ((arr[i] % a) == 0) {
                arr[i] /= a;
                k++;
            }
 
            frequecyOfPrimes[a]
                = Math.max(frequecyOfPrimes[a], k);
        }
    }
}
 
// Function which returns the element
// which should be added to array
static int elementToBeAdded(int []frequecyOfPrimes, int m)
{
    int product = 1;
 
    // To store the final answer
    int ans = 1;
 
    for (int i = 2; i <= m; i++) {
 
        if (s.contains(i))
            continue;
 
        int j = i;
        int current = 1;
 
        for (int a : primeFactors[j]) {
 
            int k = 0;
 
            // While the prime factor
            // divides the number
            while ((j % a) == 0) {
 
                j /= a;
                k++;
                if (k > frequecyOfPrimes[a]) {
                    current *= a;
                }
            }
        }
 
        // Check element which provides
        // the maximum product
        if (current > product) {
            product = current;
            ans = i;
        }
    }
    return ans;
}
 
static void findElement(int[] arr, int n, int m)
{
 
    for (int i = 0; i < n; i++)
        s.add(arr[i]);
    int frequencyOfPrimes[] = new int[10001];
    primeFactorsofLCM(frequencyOfPrimes, arr, n);
    System.out.print(elementToBeAdded(frequencyOfPrimes, m)
        +"\n");
}
 
// Driver code
public static void main(String[] args)
{
    for (int i = 0; i < 10001; i++)
        primeFactors[i] = new Vector<Integer>();
    // Precomputing the prime factors
    // of all numbers upto 10000
    findPrimeFactors();
 
    int N = 5;
    int M = 9;
    int arr[] = { 2, 5, 3, 8, 1 };
 
    findElement(arr, N, M);
}
}
 
// This code is contributed by Rajput-Ji


Python3




# Python3 program to find the element
# to be added to maximize the LCM
 
# Vector which stores the prime factors
# of all the numbers upto 10000
primeFactors = [[] for i in range(10001)]
 
s = set()
 
# Function which finds prime
# factors using sieve method
def findPrimeFactors():
 
    # Boolean array which stores
    # true if the index is prime
    primes = [True for i in range(10001)]
 
    # Sieve of Eratosthenes
    for i in range(2,10001):
 
        if (primes[i]):
            for j in range(i,10001,i):
 
                if (j != i):
                    primes[j] = False
     
                primeFactors[j].append(i)
         
 
# Function which stores frequency of every
# prime factor of LCM of the initial array
def primeFactorsofLCM(frequecyOfPrimes, arr, n):
 
    for i in range(n):
        for a in primeFactors[arr[i]]:
 
            k = 0
 
            # While the prime factor
            # divides the number
            while ((arr[i] % a) == 0):
                arr[i] = arr[i] // a
                k += 1
 
            frequecyOfPrimes[a] = max(frequecyOfPrimes[a], k)
         
 
# Function which returns the element
# which should be added to array
def elementToBeAdded(frequecyOfPrimes, m):
 
    product = 1
 
    # To store the final answer
    ans = 1
 
    for i in range(2,m+1):
 
        if (i in s):
            continue
 
        j = i
        current = 1
 
        for a in primeFactors[j]:
 
            k = 0
 
            # While the prime factor
            # divides the number
            while ((j % a) == 0):
 
                j = j // a
                k += 1
                if (k > frequecyOfPrimes[a]):
                    current *= a
                 
        # Check element which provides
        # the maximum product
        if (current > product):
            product = current
            ans = i
         
    return ans
 
 
def findElement(arr, n, m):
 
    for i in range(n):
        s.add(arr[i])
    frequencyOfPrimes = [0 for i in range(10001)]
    primeFactorsofLCM(frequencyOfPrimes, arr, n)
    print(elementToBeAdded(frequencyOfPrimes, m))
 
# Driver code
 
# Precomputing the prime factors
# of all numbers upto 10000
findPrimeFactors()
 
N = 5
M = 9
arr = [ 2, 5, 3, 8, 1 ]
 
findElement(arr, N, M)
 
# This code is contributed by shinjanpatra


C#




// C# program to find the element
// to be added to maximize the LCM
using System;
using System.Collections.Generic;
 
class GFG{
  
// List which stores the prime factors
// of all the numbers upto 10000
static List<int> []primeFactors = new List<int>[10001];
static HashSet<int> s = new HashSet<int>();
  
// Function which finds prime
// factors using sieve method
static void findPrimeFactors()
{
  
    // Boolean array which stores
    // true if the index is prime
    bool []primes = new bool[10001];
    for (int i = 0; i < 10001; i++)
        primes[i] = true;
  
    // Sieve of Eratosthenes
    for (int i = 2; i < 10001; i++) {
  
        if (primes[i]) {
            for (int j = i; j < 10001; j += i) {
  
                if (j != i) {
                    primes[j] = false;
                }
                primeFactors[j].Add(i);
            }
        }
    }
}
  
// Function which stores frequency of every
// prime factor of LCM of the initial array
static void primeFactorsofLCM(int []frequecyOfPrimes,
                    int[] arr, int n)
{
  
    for (int i = 0; i < n; i++) {
        foreach (int a in primeFactors[arr[i]]) {
  
            int k = 0;
  
            // While the prime factor
            // divides the number
            while ((arr[i] % a) == 0) {
                arr[i] /= a;
                k++;
            }
  
            frequecyOfPrimes[a]
                = Math.Max(frequecyOfPrimes[a], k);
        }
    }
}
  
// Function which returns the element
// which should be added to array
static int elementToBeAdded(int []frequecyOfPrimes, int m)
{
    int product = 1;
  
    // To store the readonly answer
    int ans = 1;
  
    for (int i = 2; i <= m; i++) {
  
        if (s.Contains(i))
            continue;
  
        int j = i;
        int current = 1;
  
        foreach (int a in primeFactors[j]) {
  
            int k = 0;
  
            // While the prime factor
            // divides the number
            while ((j % a) == 0) {
  
                j /= a;
                k++;
                if (k > frequecyOfPrimes[a]) {
                    current *= a;
                }
            }
        }
  
        // Check element which provides
        // the maximum product
        if (current > product) {
            product = current;
            ans = i;
        }
    }
    return ans;
}
  
static void findElement(int[] arr, int n, int m)
{
  
    for (int i = 0; i < n; i++)
        s.Add(arr[i]);
    int []frequencyOfPrimes = new int[10001];
    primeFactorsofLCM(frequencyOfPrimes, arr, n);
    Console.Write(elementToBeAdded(frequencyOfPrimes, m)
        +"\n");
}
  
// Driver code
public static void Main(String[] args)
{
    for (int i = 0; i < 10001; i++)
        primeFactors[i] = new List<int>();
 
    // Precomputing the prime factors
    // of all numbers upto 10000
    findPrimeFactors();
  
    int N = 5;
    int M = 9;
    int []arr = { 2, 5, 3, 8, 1 };
  
    findElement(arr, N, M);
}
}
  
// This code is contributed by PrinciRaj1992


Javascript




<script>
// Javascript program to find the element
// to be added to maximize the LCM
 
// Vector which stores the prime factors
// of all the numbers upto 10000
let primeFactors = new Array();
 
for(let i = 0;  i < 10001; i++){
    primeFactors.push([])
}
 
let s = new Set();
 
// Function which finds prime
// factors using sieve method
function findPrimeFactors()
{
 
    // Boolean array which stores
    // true if the index is prime
    let primes = new Array(10001);
    primes.fill(true)
 
    // Sieve of Eratosthenes
    for (let i = 2; i < 10001; i++) {
 
        if (primes[i]) {
            for (let j = i; j < 10001; j += i) {
 
                if (j != i) {
                    primes[j] = false;
                }
                primeFactors[j].push(i);
            }
        }
    }
}
 
// Function which stores frequency of every
// prime factor of LCM of the initial array
function primeFactorsofLCM(frequecyOfPrimes, arr, n)
{
 
    for (let i = 0; i < n; i++) {
        for (let a of primeFactors[arr[i]]) {
 
            let k = 0;
 
            // While the prime factor
            // divides the number
            while ((arr[i] % a) == 0) {
                arr[i] /= a;
                k++;
            }
 
            frequecyOfPrimes[a]
                = Math.max(frequecyOfPrimes[a], k);
        }
    }
}
 
// Function which returns the element
// which should be added to array
function elementToBeAdded(frequecyOfPrimes, m)
{
    let product = 1;
 
    // To store the final answer
    let ans = 1;
 
    for (let i = 2; i <= m; i++) {
 
        if (s.has(i))
            continue;
 
        let j = i;
        let current = 1;
 
        for (let a of primeFactors[j]) {
 
            let k = 0;
 
            // While the prime factor
            // divides the number
            while ((j % a) == 0) {
 
                j /= a;
                k++;
                if (k > frequecyOfPrimes[a]) {
                    current *= a;
                }
            }
        }
 
        // Check element which provides
        // the maximum product
        if (current > product) {
            product = current;
            ans = i;
        }
    }
    return ans;
}
 
function findElement(arr, n, m)
{
 
    for (let i = 0; i < n; i++)
        s.add(arr[i]);
    let frequencyOfPrimes = new Array(10001).fill(0);
    primeFactorsofLCM(frequencyOfPrimes, arr, n);
    document.write(elementToBeAdded(frequencyOfPrimes, m) + "<br>");
}
 
// Driver code
 
 
    // Precomputing the prime factors
    // of all numbers upto 10000
    findPrimeFactors();
 
    let N = 5;
    let M = 9;
    let arr = [ 2, 5, 3, 8, 1 ];
 
    findElement(arr, N, M);
 
// This code is contributed by _saurabh_jaiswal
</script>


Output: 

7

 

Time Complexity: O(N * log N + M * log M)
 



Last Updated : 09 Jun, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads