📜  数组元素的LCM的主要因素

📅  最后修改于: 2021-04-26 18:21:00             🧑  作者: Mango

给定一个数组arr []使得1 <= arr [i] <= 10 ^ 12,任务是找到数组元素LCM的主要因子。

例子:

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

解决此问题的简单方法是找到数组中n个元素的LCM。首先初始化lcm = 1,然后对数组中的每个元素进行迭代,并使用公式LCM(a,b)=(a * b)/ gcd(a,b)用新元素找到先前结果的lcm,即lcm =(lcm * arr [i])/ gcd(lcm,arr [i])。找到所有n个元素的LCM之后,我们可以计算LCM的所有素数。

由于这里的约束很大,因此我们无法实现上述方法来解决此问题,因为在计算LCM(a,b)时,我们需要计算a * b,如果a,b的值都为10 ^ 12,那么它将超出限制整数大小。我们使用sundaram筛子和数字的素因数分解以另一种方式解决这个问题。众所周知,如果LCM(a,b)= k,那么a或b的任何素因也将是’k’的素因。

  • 取大小为10 ^ 6的array factor []并将其初始化为0,因为任意数量的素数始终小于等于其平方根,并且在我们的约束中arr [i] <= 10 ^ 12。
  • 生成所有小于等于10 ^ 6的素数,并将它们存储在另一个数组中。
  • 现在,一个接一个地计算数组中每个数字的所有素数,并在factor []数组中将它们标记为1。
  • 现在遍历factor []数组并打印所有标记为1的索引,因为它们将是给定数组中n个数字的1cm的质数。

以下是上述想法的实现。

C++
// C++ program to find prime factors of LCM of array elements
#include 
using namespace std;
  
const int MAX  = 1000000;
typedef long long int ll;
  
// array to store all prime less than and equal to 10^6
vector  primes;
  
// utility function for sieve of sundaram
void sieve()
{
    int n = MAX;
  
    // In general Sieve of Sundaram, produces primes smaller
    // than (2*x + 2) for a number given number x. Since
    // we want primes smaller than n, we reduce n to half
    int nNew = (n)/2;
  
    // This array is used to separate numbers of the form
    // i+j+2ij from others where 1 <= i <= j
    bool marked[nNew + 100];
  
    // Initalize all elements as not marked
    memset(marked, false, sizeof(marked));
  
    // Main logic of Sundaram. Mark all numbers which do not
    // generate prime number by doing 2*i+1
    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;
  
    // Since 2 is a prime number
    primes.push_back(2);
  
    // Print other primes. Remaining primes are of the form
    // 2*i + 1 such that marked[i] is false.
    for (int i=1; i<=nNew; i++)
        if (marked[i] == false)
            primes.push_back(2*i + 1);
}
  
// Function to find prime factors of n elements of
// given array
void primeLcm(ll arr[], int n )
{
    // factors[] --> array to mark all prime factors of
    // lcm of array elements
    int factors[MAX] = {0};
  
    // One by one calculate prime factors of number
    // and mark them in factors[] array
    for (int i=0; i duplicate of original element to
        //          perform operation
        ll copy = arr[i];
  
        // sqr --> square root of current number 'copy'
        // because all prime factors are always less
        // than and equal to square root of given number
        int sqr = sqrt(copy);
  
        // check divisibility with prime factor
        for (int j=0; primes[j]<=sqr; j++)
        {
            // if current prime number is factor of 'copy'
            if (copy%primes[j] == 0)
            {
                // divide with current prime factor until
                // it can divide the number
                while (copy%primes[j] == 0)
                    copy = copy/primes[j];
  
                // mark current prime factor as 1 in
                // factors[] array
                factors[primes[j]] = 1;
            }
        }
  
        // After calculating exponents of all prime factors
        // either value of 'copy' will be 1 because of
        // complete divisibility or remaining value of
        // 'copy' will be surely a prime , so we will
        // also mark this prime as a factor
        if (copy > 1)
            factorsCopy = 1;
    }
  
    // if 2 is prime factor of lcm of all elements
    // in given array
    if (factors[2] == 1)
        cout << 2 << " ";
  
    // traverse to print all prime factors of lcm of
    // all elements in given array
    for (int i=3; i<=MAX; i=i+2)
        if (factors[i] == 1)
            cout << i << " ";
}
  
// Driver program to run the case
int main()
{
    sieve();
    ll arr[] = {20, 10, 15, 60};
    int n = sizeof(arr)/sizeof(arr[0]);
    primeLcm(arr, n);
    return 0;
}


Java
// Java program to find prime 
// factors of LCM of array elements
import java.util.*;
  
class GFG
{
  
static int MAX = 1000000;
  
// array to store all prime less 
// than and equal to 10^6
static ArrayList primes = new ArrayList();
  
// utility function for sieve of sundaram
static void sieve()
{
    int n = MAX;
  
    // In general Sieve of Sundaram, 
    // produces primes smaller than 
    // (2*x + 2) for a number given 
    // number x. Since we want primes
    // smaller than n, we reduce n to half
    int nNew = (n) / 2;
  
    // This array is used to separate
    // numbers of the form i+j+2ij 
    // from others where 1 <= i <= j
    boolean[] marked = new boolean[nNew + 100];
  
  
    // Main logic of Sundaram. Mark all
    // numbers which do not generate 
    // prime number by doing 2*i+1
    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;
  
    // Since 2 is a prime number
    primes.add(2);
  
    // Print other primes. Remaining 
    // primes are of the form 2*i + 1 
    // such that marked[i] is false.
    for (int i = 1; i <= nNew; i++)
        if (marked[i] == false)
            primes.add(2 * i + 1);
}
  
// Function to find prime factors 
// of n elements of given array
static void primeLcm(int[] arr, int n )
{
    // factors[] --> array to mark all prime 
    // factors of lcm of array elements
    int[] factors = new int[MAX];
  
    // One by one calculate prime factors of number
    // and mark them in factors[] array
    for (int i = 0; i < n; i++)
    {
        // copy --> duplicate of original element to
        //  perform operation
        int copy = arr[i];
  
        // sqr --> square root of current number 'copy'
        // because all prime factors are always less
        // than and equal to square root of given number
        int sqr = (int)Math.sqrt(copy);
  
        // check divisibility with prime factor
        for (int j = 0; primes.get(j) <= sqr; j++)
        {
            // if current prime number is factor of 'copy'
            if (copy % primes.get(j) == 0)
            {
                // divide with current prime factor until
                // it can divide the number
                while (copy % primes.get(j) == 0)
                    copy = copy / primes.get(j);
  
                // mark current prime factor as 1 in
                // factors[] array
                factors[primes.get(j)] = 1;
            }
        }
  
        // After calculating exponents of all prime factors
        // either value of 'copy' will be 1 because of
        // complete divisibility or remaining value of
        // 'copy' will be surely a prime , so we will
        // also mark this prime as a factor
        if (copy > 1)
            factorsCopy = 1;
    }
  
    // if 2 is prime factor of lcm of all elements
    // in given array
    if (factors[2] == 1)
        System.out.print("2 ");
  
    // traverse to print all prime factors of lcm of
    // all elements in given array
    for (int i = 3; i <= MAX; i = i + 2)
        if (factors[i] == 1)
            System.out.print(i+" ");
}
  
// Driver code
public static void main (String[] args)
{
    sieve();
    int[] arr = {20, 10, 15, 60};
    int n = arr.length;
    primeLcm(arr, n);
}
}
  
// This code is contributed by chandan_jnu


Python3
# Python3 program to find prime factors 
# of LCM of array elements 
import math;
MAX = 10000; 
  
# array to store all prime less than
# and equal to 10^6 
primes = []; 
  
# utility function for sieve of sundaram 
def sieve(): 
  
    n = MAX; 
  
    # In general Sieve of Sundaram, produces 
    # primes smaller than (2*x + 2) for a 
    # number given number x. Since we want 
    # primes smaller than n, we reduce n to half 
    nNew = int(n / 2); 
  
    # This array is used to separate numbers of 
    # the form i+j+2ij from others where 1 <= i <= j 
    marked = [False] * (nNew + 100); 
  
  
    # Main logic of Sundaram. Mark all numbers 
    # which do not generate prime number by
    # doing 2*i+1 
    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; 
  
    # Since 2 is a prime number 
    primes.append(2); 
  
    # Print other primes. Remaining primes 
    # are of the form 2*i + 1 such that 
    # marked[i] is false. 
    for i in range(1, nNew + 1): 
        if (marked[i] == False): 
            primes.append(2 * i + 1); 
  
# Function to find prime factors of 
# n elements of given array 
def primeLcm(arr, n ): 
  
    # factors[] --> array to mark all prime 
    # factors of lcm of array elements 
    factors = [0] * (MAX); 
  
    # One by one calculate prime factors of 
    # number and mark them in factors[] array 
    for i in range(n):
          
        # copy --> duplicate of original
        # element to perform operation 
        copy = arr[i]; 
  
        # sqr --> square root of current number 
        # 'copy' because all prime factors are 
        # always less than and equal to square 
        # root of given number 
        sqr = int(math.sqrt(copy)); 
  
        # check divisibility with prime factor
        j = 0;
        while (primes[j] <= sqr): 
          
            # if current prime number is 
            # factor of 'copy' 
            if (copy % primes[j] == 0): 
                  
                # divide with current prime factor 
                # until it can divide the number 
                while (copy % primes[j] == 0): 
                    copy = int(copy / primes[j]); 
  
                # mark current prime factor as 1 
                # in factors[] array 
                factors[primes[j]] = 1; 
            j += 1; 
  
        # After calculating exponents of all prime 
        # factors either value of 'copy' will be 1 
        # because of complete divisibility or 
        # remaining value of 'copy' will be surely 
        # a prime, so we will also mark this prime
        # as a factor 
        if (copy > 1): 
            factorsCopy = 1; 
  
    # if 2 is prime factor of lcm of 
    # all elements in given array 
    if (factors[2] == 1): 
        print("2 ", end = ""); 
  
    # traverse to print all prime factors of 
    # lcm of all elements in given array 
    for i in range(3, MAX + 1, 2): 
        if (factors[i] == 1): 
            print(i, end = " "); 
  
# Driver Code
sieve(); 
arr = [20, 10, 15, 60]; 
n = len(arr); 
primeLcm(arr, n);
  
# This code is contributed by chandan_jnu


C#
// C# program to find prime 
// factors of LCM of array elements
using System;
using System.Collections;
  
class GFG
{
  
static int MAX = 1000000;
  
// array to store all prime less 
// than and equal to 10^6
static ArrayList primes = new ArrayList();
  
// utility function for sieve of sundaram
static void sieve()
{
    int n = MAX;
  
    // In general Sieve of Sundaram, 
    // produces primes smaller than 
    // (2*x + 2) for a number given 
    // number x. Since we want primes
    // smaller than n, we reduce n to half
    int nNew = (n) / 2;
  
    // This array is used to separate
    // numbers of the form i+j+2ij 
    // from others where 1 <= i <= j
    bool[] marked = new bool[nNew + 100];
  
  
    // Main logic of Sundaram. Mark all
    // numbers which do not generate 
    // prime number by doing 2*i+1
    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;
  
    // Since 2 is a prime number
    primes.Add(2);
  
    // Print other primes. Remaining 
    // primes are of the form 2*i + 1 
    // such that marked[i] is false.
    for (int i = 1; i <= nNew; i++)
        if (marked[i] == false)
            primes.Add(2 * i + 1);
}
  
// Function to find prime factors 
// of n elements of given array
static void primeLcm(int[] arr, int n )
{
    // factors[] --> array to 
    // mark all prime factors
    // of lcm of array elements
    int[] factors = new int[MAX];
  
    // One by one calculate prime
    // factors of number and mark
    // them in factors[] array
    for (int i = 0; i < n; i++)
    {
        // copy --> duplicate of original 
        // element to perform operation
        int copy = arr[i];
  
        // sqr --> square root of current
        // number 'copy' because all prime
        // factors are always less than and 
        // equal to square root of given number
        int sqr = (int)Math.Sqrt(copy);
  
        // check divisibility with prime factor
        for (int j = 0; (int)primes[j] <= sqr; j++)
        {
            // if current prime number is factor of 'copy'
            if (copy % (int)primes[j] == 0)
            {
                // divide with current prime factor until
                // it can divide the number
                while (copy % (int)primes[j] == 0)
                    copy = copy / (int)primes[j];
  
                // mark current prime factor as 1 in
                // factors[] array
                factors[(int)primes[j]] = 1;
            }
        }
  
        // After calculating exponents of all prime factors
        // either value of 'copy' will be 1 because of
        // complete divisibility or remaining value of
        // 'copy' will be surely a prime , so we will
        // also mark this prime as a factor
        if (copy > 1)
            factorsCopy = 1;
    }
  
    // if 2 is prime factor of lcm of all elements
    // in given array
    if (factors[2] == 1)
        Console.Write("2 ");
  
    // traverse to print all prime factors of lcm of
    // all elements in given array
    for (int i = 3; i <= MAX; i = i + 2)
        if (factors[i] == 1)
            Console.Write(i+" ");
}
  
// Driver code
static void Main()
{
    sieve();
    int[] arr = {20, 10, 15, 60};
    int n = arr.Length;
    primeLcm(arr, n);
}
}
  
// This code is contributed by chandan_jnu


PHP
 array to mark all prime 
    // factors of lcm of array elements 
    $factors = array_fill(0, $MAX, 0); 
  
    // One by one calculate prime factors of 
    // number and mark them in factors[] array 
    for ($i = 0; $i < $n; $i++) 
    { 
        // copy --> duplicate of original
        // element to perform operation 
        $copy = $arr[$i]; 
  
        // sqr --> square root of current number 
        // 'copy' because all prime factors are 
        // always less than and equal to square 
        // root of given number 
        $sqr = (int)sqrt($copy); 
  
        // check divisibility with prime factor 
        for ($j = 0; $primes[$j] <= $sqr; $j++) 
        { 
            // if current prime number is factor 
            // of 'copy' 
            if ($copy % $primes[$j] == 0) 
            { 
                // divide with current prime factor 
                // until it can divide the number 
                while ($copy % $primes[$j] == 0) 
                    $copy = (int)($copy / $primes[$j]); 
  
                // mark current prime factor as 1 
                // in factors[] array 
                $factors[$primes[$j]] = 1; 
            } 
        } 
  
        // After calculating exponents of all prime 
        // factors either value of 'copy' will be 1 
        // because of complete divisibility or remaining 
        // value of 'copy' will be surely a prime , so 
        // we will also mark this prime as a factor 
        if ($copy > 1) 
            $factors[$copy] = 1; 
    } 
  
    // if 2 is prime factor of lcm of all 
    // elements in given array 
    if ($factors[2] == 1) 
        echo "2 "; 
  
    // traverse to print all prime factors of 
    // lcm of all elements in given array 
    for ($i = 3; $i <= $MAX; $i = $i + 2) 
        if ($factors[$i] == 1) 
            echo $i . " "; 
} 
  
// Driver Code
sieve(); 
$arr = array(20, 10, 15, 60); 
$n = count($arr); 
primeLcm($arr, $n);
  
// This code is contributed by chandan_jnu
?>


输出:

2 3 5