Prime factors of LCM of array elements
Given an array arr[] such that 1 <= arr[i] <= 10^12, the task is to find prime factors of LCM of array elements.
Examples:
Input : arr[] = {1, 2, 3, 4, 5, 6, 7, 8}
Output : 2 3 5 7
// LCM of n elements is 840 and 840 = 2*2*2*3*5*7
// so prime factors would be 2, 3, 5, 7
Input : arr[] = {20, 10, 15, 60}
Output : 2 3 5
// LCM of n elements is 60 and 60 = 2*2*3*5,
// so prime factors would be 2,3,5
A simple solution for this problem is to find LCM of n elements in array. First initialize lcm = 1, then iterate for each element in array and find the lcm of previous result with new element using formula LCM(a, b) = (a * b) / gcd(a, b) i.e., lcm = (lcm * arr[i]) / gcd(lcm, arr[i]). After finding LCM of all n elements we can calculate all prime factors of LCM.
Since here constraints are large, we can not implement above method to solve this problem because while calculating LCM(a, b) we need to calculate a*b and if a,b both are of value 10^12 so it will exceed the limit of integer size. We proceed for this problem in another way using sieve of sundaram and prime factorization of a number. As we know if LCM(a,b) = k so any prime factor of a or b will also be the prime factor of ‘k’.
- Take an array factor[] of size 10^6 and initialize it with 0 because prime factor of any number are always less than and equal to its square root and in our constraint arr[i] <= 10^12.
- Generate all primes less than and equal to 10^6 and store them in another array.
- Now one by one calculate all prime factors of each number in array and mark them as 1 in factor[] array.
- Now traverse factor[] array and print all indexes which are marked as 1 because these will be prime factors of lcm of n numbers in given array.
Below is the implementation of above idea.
C++
#include <bits/stdc++.h>
using namespace std;
const int MAX = 1000000;
typedef long long int ll;
vector < int > primes;
void sieve()
{
int n = MAX;
int nNew = (n)/2;
bool marked[nNew + 100];
memset (marked, false , sizeof (marked));
int tmp= sqrt (n);
for ( int i=1; i<=(tmp-1)/2; i++)
for ( int j=(i*(i+1))<<1; j<=nNew; j=j+2*i+1)
marked[j] = true ;
primes.push_back(2);
for ( int i=1; i<=nNew; i++)
if (marked[i] == false )
primes.push_back(2*i + 1);
}
void primeLcm(ll arr[], int n )
{
int factors[MAX] = {0};
for ( int i=0; i<n; i++)
{
ll copy = arr[i];
int sqr = sqrt (copy);
for ( int j=0; primes[j]<=sqr; j++)
{
if (copy%primes[j] == 0)
{
while (copy%primes[j] == 0)
copy = copy/primes[j];
factors[primes[j]] = 1;
}
}
if (copy > 1)
factors[copy] = 1;
}
if (factors[2] == 1)
cout << 2 << " " ;
for ( int i=3; i<=MAX; i=i+2)
if (factors[i] == 1)
cout << i << " " ;
}
int main()
{
sieve();
ll arr[] = {20, 10, 15, 60};
int n = sizeof (arr)/ sizeof (arr[0]);
primeLcm(arr, n);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static int MAX = 1000000 ;
static ArrayList<Integer> primes = new ArrayList<Integer>();
static void sieve()
{
int n = MAX;
int nNew = (n) / 2 ;
boolean [] marked = new boolean [nNew + 100 ];
int tmp = ( int )Math.sqrt(n);
for ( int i = 1 ; i <= (tmp - 1 ) / 2 ; i++)
for ( int j = (i * (i + 1 )) << 1 ;
j <= nNew; j = j + 2 * i + 1 )
marked[j] = true ;
primes.add( 2 );
for ( int i = 1 ; i <= nNew; i++)
if (marked[i] == false )
primes.add( 2 * i + 1 );
}
static void primeLcm( int [] arr, int n )
{
int [] factors = new int [MAX];
for ( int i = 0 ; i < n; i++)
{
int copy = arr[i];
int sqr = ( int )Math.sqrt(copy);
for ( int j = 0 ; primes.get(j) <= sqr; j++)
{
if (copy % primes.get(j) == 0 )
{
while (copy % primes.get(j) == 0 )
copy = copy / primes.get(j);
factors[primes.get(j)] = 1 ;
}
}
if (copy > 1 )
factors[copy] = 1 ;
}
if (factors[ 2 ] == 1 )
System.out.print( "2 " );
for ( int i = 3 ; i <= MAX; i = i + 2 )
if (factors[i] == 1 )
System.out.print(i+ " " );
}
public static void main (String[] args)
{
sieve();
int [] arr = { 20 , 10 , 15 , 60 };
int n = arr.length;
primeLcm(arr, n);
}
}
|
Python3
import math;
MAX = 10000 ;
primes = [];
def sieve():
n = MAX ;
nNew = int (n / 2 );
marked = [ False ] * (nNew + 100 );
tmp = int (math.sqrt(n));
for i in range ( 1 , int ((tmp - 1 ) / 2 ) + 1 ):
for j in range ((i * (i + 1 )) << 1 ,
nNew + 1 , 2 * i + 1 ):
marked[j] = True ;
primes.append( 2 );
for i in range ( 1 , nNew + 1 ):
if (marked[i] = = False ):
primes.append( 2 * i + 1 );
def primeLcm(arr, n ):
factors = [ 0 ] * ( MAX );
for i in range (n):
copy = arr[i];
sqr = int (math.sqrt(copy));
j = 0 ;
while (primes[j] < = sqr):
if (copy % primes[j] = = 0 ):
while (copy % primes[j] = = 0 ):
copy = int (copy / primes[j]);
factors[primes[j]] = 1 ;
j + = 1 ;
if (copy > 1 ):
factors[copy] = 1 ;
if (factors[ 2 ] = = 1 ):
print ( "2 " , end = "");
for i in range ( 3 , MAX + 1 , 2 ):
if (factors[i] = = 1 ):
print (i, end = " " );
sieve();
arr = [ 20 , 10 , 15 , 60 ];
n = len (arr);
primeLcm(arr, n);
|
C#
using System;
using System.Collections;
class GFG
{
static int MAX = 1000000;
static ArrayList primes = new ArrayList();
static void sieve()
{
int n = MAX;
int nNew = (n) / 2;
bool [] marked = new bool [nNew + 100];
int tmp = ( int )Math.Sqrt(n);
for ( int i = 1; i <= (tmp - 1) / 2; i++)
for ( int j = (i * (i + 1)) << 1;
j <= nNew; j = j + 2 * i + 1)
marked[j] = true ;
primes.Add(2);
for ( int i = 1; i <= nNew; i++)
if (marked[i] == false )
primes.Add(2 * i + 1);
}
static void primeLcm( int [] arr, int n )
{
int [] factors = new int [MAX];
for ( int i = 0; i < n; i++)
{
int copy = arr[i];
int sqr = ( int )Math.Sqrt(copy);
for ( int j = 0; ( int )primes[j] <= sqr; j++)
{
if (copy % ( int )primes[j] == 0)
{
while (copy % ( int )primes[j] == 0)
copy = copy / ( int )primes[j];
factors[( int )primes[j]] = 1;
}
}
if (copy > 1)
factors[copy] = 1;
}
if (factors[2] == 1)
Console.Write( "2 " );
for ( int i = 3; i <= MAX; i = i + 2)
if (factors[i] == 1)
Console.Write(i+ " " );
}
static void Main()
{
sieve();
int [] arr = {20, 10, 15, 60};
int n = arr.Length;
primeLcm(arr, n);
}
}
|
PHP
<?php
$MAX = 10000;
$primes = array ();
function sieve()
{
global $MAX , $primes ;
$n = $MAX ;
$nNew = (int)( $n / 2);
$marked = array_fill (0, $nNew + 100, false);
$tmp = (int)sqrt( $n );
for ( $i = 1; $i <= (int)(( $tmp - 1) / 2); $i ++)
for ( $j = ( $i * ( $i + 1)) << 1;
$j <= $nNew ; $j = $j + 2 * $i + 1)
$marked [ $j ] = true;
array_push ( $primes , 2);
for ( $i = 1; $i <= $nNew ; $i ++)
if ( $marked [ $i ] == false)
array_push ( $primes , 2 * $i + 1);
}
function primeLcm( $arr , $n )
{
global $MAX , $primes ;
$factors = array_fill (0, $MAX , 0);
for ( $i = 0; $i < $n ; $i ++)
{
$copy = $arr [ $i ];
$sqr = (int)sqrt( $copy );
for ( $j = 0; $primes [ $j ] <= $sqr ; $j ++)
{
if ( $copy % $primes [ $j ] == 0)
{
while ( $copy % $primes [ $j ] == 0)
$copy = (int)( $copy / $primes [ $j ]);
$factors [ $primes [ $j ]] = 1;
}
}
if ( $copy > 1)
$factors [ $copy ] = 1;
}
if ( $factors [2] == 1)
echo "2 " ;
for ( $i = 3; $i <= $MAX ; $i = $i + 2)
if ( $factors [ $i ] == 1)
echo $i . " " ;
}
sieve();
$arr = array (20, 10, 15, 60);
$n = count ( $arr );
primeLcm( $arr , $n );
?>
|
Javascript
<script>
let MAX = 1000000;
let primes = [];
function sieve()
{
let n = MAX;
let nNew = parseInt((n) / 2, 10);
let marked = new Array(nNew + 100);
marked.fill( false );
let tmp = parseInt(Math.sqrt(n), 10);
for (let i = 1; i <= parseInt((tmp - 1) / 2, 10); i++)
for (let j = (i * (i + 1)) << 1; j <= nNew;
j = j + 2 * i + 1)
marked[j] = true ;
primes.push(2);
for (let i = 1; i <= nNew; i++)
if (marked[i] == false )
primes.push(2 * i + 1);
}
function primeLcm(arr, n)
{
let factors = new Array(MAX);
for (let i = 0; i < n; i++)
{
let copy = arr[i];
let sqr = parseInt(Math.sqrt(copy), 10);
for (let j = 0; primes[j] <= sqr; j++)
{
if (copy % primes[j] == 0)
{
while (copy % primes[j] == 0)
copy = parseInt(copy / primes[j], 10);
factors[primes[j]] = 1;
}
}
if (copy > 1)
factors[copy] = 1;
}
if (factors[2] == 1)
document.write( "2 " );
for (let i = 3; i <= MAX; i = i + 2)
if (factors[i] == 1)
document.write(i+ " " );
}
sieve();
let arr = [20, 10, 15, 60];
let n = arr.length;
primeLcm(arr, n);
</script>
|
Output:
2 3 5
Last Updated :
11 Sep, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...