📜  N模M的LCM

📅  最后修改于: 2021-04-22 07:37:49             🧑  作者: Mango

给定一个整数数组arr [] ,任务是找到该数组所有元素模L的LCM,其中M = 10 9 + 7
例子:

方法:如果您经过计算数组元素的LCM的文章,想到的第一种方法是在计算ansarr [i]的LCM的每一步取模。

但是,这种方法是错误的,并且可以在以下示例中实现该错误:

注意:每当2个数字的LCM变为> M时,该方法将不起作用。
正确的方法是对数组的元素进行质因子分解,并跟踪每个元素的每个质数的最大功效。 LCM将是这些素数提高到阵列中最高功率的产物。
插图

p为数组元素的素数x为整个数组的最高幂。然后,

使用上面的公式,我们可以轻松地计算整个阵列的LCM,并且还可以解决我们的MOD问题。简化表达式,我们得到:

由于模运算是通过乘法分配的,因此我们可以安全地编写以下表达式。

现在,出现了关于如何有效地计算素因子及其幂的问题。为此,我们可以使用Eratosthenes的筛子。请参阅此文章:使用筛子计算素因及其功效。
下面是上述方法的实现:

C++
// C++ program to compute LCM of array elements modulo M
#include 
#define F first
#define S second
#define MAX 10000003
using namespace std;
 
typedef long long ll;
const int mod = 1000000007;
 
int prime[MAX];
unordered_map max_map;
 
// Function to return a^n
int power(int a, int n)
{
    if (n == 0)
        return 1;
    int p = power(a, n / 2) % mod;
    p = (p * p) % mod;
    if (n & 1)
        p = (p * a) % mod;
    return p;
}
 
// Function to find the smallest prime factors
// of numbers upto MAX
void sieve()
{
    prime[0] = prime[1] = 1;
    for (int i = 2; i < MAX; i++) {
        if (prime[i] == 0) {
            for (int j = i * 2; j < MAX; j += i) {
                if (prime[j] == 0) {
                    prime[j] = i;
                }
            }
            prime[i] = i;
        }
    }
}
 
// Function to return the LCM modulo M
ll lcmModuloM(const int* ar, int n)
{
 
    for (int i = 0; i < n; i++) {
        int num = ar[i];
        unordered_map temp;
 
        // Temp stores mapping of prime factor to
        // its power for the current element
        while (num > 1) {
 
            // Factor is the smallest prime factor of num
            int factor = prime[num];
 
            // Increase count of factor in temp
            temp[factor]++;
 
            // Reduce num by its prime factor
            num /= factor;
        }
 
        for (auto it : temp) {
 
            // Store the highest power of every prime
            // found till now in a new map max_map
            max_map[it.first] = max(max_map[it.first], it.second);
        }
    }
 
    ll ans = 1;
 
    for (auto it : max_map) {
 
        // LCM is product of primes to their highest powers modulo M
        ans = (ans * power(it.F, it.S)) % mod;
    }
 
    return ans;
}
 
// Driver code
int main()
{
    sieve();
    int arr[] = { 36, 500, 480, 343 };
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << lcmModuloM(arr, n);
    return 0;
}


Java
// Java program to compute LCM of
// array elements modulo M
import java.util.*;
 
class GFG{
 
final static int MAX = 10000003;
final static int mod = 1000000007;
static int[] prime = new int[MAX];
 
// Function to return a^n    
public static int power(int a, int n)
{
    if(n == 0)
       return 1;
     
    int p = power(a, n / 2) % mod;
    p = (p * p) % mod;
     
    if((n & 1) > 0)
       p = (p * a) % mod;
         
    return p;
}
     
// Function to find the smallest prime
// factors of numbers upto MAX
public static void sieve()
{
    prime[0] = 1;
    prime[1] = 1;
     
    for(int i = 2; i < MAX; i++)
    {
       if(prime[i] == 0)
       {
           for(int j = i * 2;
                   j < MAX; j += i)
           {
              if(prime[j] == 0)
              {
                  prime[j] = i;
              }
           }
           prime[i] = i;
       }
    } 
}
     
// Function to return the LCM modulo M    
public static long lcmModuloM(int[] arr, int n)
{
    HashMap maxMap = new HashMap<>();
     
    for(int i = 0; i < n; i++)
    {
        HashMap temp = new HashMap<>();
        int num = arr[i];
         
        // Temp stores mapping of prime 
        // factor to its power for the
        // current element
        while(num > 1)
        {
             
            // Factor is the smallest prime
            // factor of num
            int factor = prime[num];
             
            if(temp.containsKey(factor))
               temp.put(factor, temp.get(factor) + 1);
            else
               temp.put(factor, 1);
             
            // Factor is the smallest prime
            // factor of num    
            num = num / factor;
        }
         
        for(Map.Entry m : temp.entrySet())
        {
           if(maxMap.containsKey(m.getKey()))
           {
               int maxPower = Math.max(m.getValue(),
                                       maxMap.get(
                                       m.getKey()));
               maxMap.put(m.getKey(), maxPower);
           }
           else
           {
               maxMap.put(m.getKey(),m.getValue());
           }
        }
    }
     
    long ans = 1;
    for(Map.Entry m : maxMap.entrySet())
    {
         
       // LCM is product of primes to their
       // highest powers modulo M
       ans = (ans * power(m.getKey(),
                          m.getValue()) % mod);
    }
     
    return ans;
}
 
// Driver code   
public static void main(String[] args)
{
    sieve();
    int[] arr = new int[]{36, 500, 480, 343 };
    int n = arr.length;
     
    System.out.println(lcmModuloM(arr, n));
}
}
 
// This code is contributed by parshavnahta97


Python3
# Python3 program to compute LCM of
# array elements modulo M
MAX = 10000003
 
mod = 1000000007
 
prime = [0 for i in range(MAX)]
 
max_map = dict()
 
# function to return a^n
def power(a, n):
     
    if n == 0:
        return 1
    p = power(a, n // 2) % mod
    p = (p * p) % mod
     
    if n & 1:
        p = (p * a) % mod
    return p
 
# function to find the smallest prime
# factors of numbers upto MAX
def sieve():
    prime[0], prime[1] = 1, 1
    for i in range(2, MAX):
        if prime[i] == 0:
            for j in range(i * 2, MAX, i):
                if prime[j] == 0:
                    prime[j] = i
            prime[i] = i
 
# function to return the LCM modulo M
def lcmModuloM(arr, n):
     
    for i in range(n):
        num = arr[i]
         
        temp = dict()
         
        # temp stores mapping of prime factors
        # to its power for the current element
        while num > 1:
              
            # factor is the smallest prime
            # factor of num
            factor = prime[num]
             
            # Increase count of factor in temp
            if factor in temp.keys():
                temp[factor] += 1
            else:
                temp[factor] = 1
                 
            # Reduce num by its prime factor
            num = num // factor
             
        for i in temp:
            # store the higest power of every prime
            # found till now in a new map max_map
            if i in max_map.keys():
                max_map[i] = max(max_map[i], temp[i])
            else:
                max_map[i] = temp[i]
             
    ans = 1
     
    for i in max_map:
         
        # LCM is product of primes to their
        # higest powers modulo M
        ans = (ans * power(i, max_map[i])) % mod
    return ans
 
# Driver code
sieve()
arr = [36, 500, 480, 343]
n = len(arr)
print(lcmModuloM(arr, n))
 
# This code is contributed
# by Mohit kumar 29


C#
// C# program to compute LCM of
// array elements modulo M
using System;
using System.Collections.Generic;
class GFG{
 
readonly static int MAX = 10000003;
readonly static int mod = 1000000007;
static int[] prime = new int[MAX];
 
// Function to return a^n    
public static int power(int a,
                        int n)
{
  if(n == 0)
    return 1;
 
  int p = power(a, n / 2) %
          mod;
  p = (p * p) % mod;
 
  if((n & 1) > 0)
    p = (p * a) % mod;
 
  return p;
}
     
// Function to find the smallest
// prime factors of numbers upto
// MAX
public static void sieve()
{
  prime[0] = 1;
  prime[1] = 1;
 
  for(int i = 2; i < MAX; i++)
  {
    if(prime[i] == 0)
    {
      for(int j = i * 2;
              j < MAX; j += i)
      {
        if(prime[j] == 0)
        {
          prime[j] = i;
        }
      }
      prime[i] = i;
    }
  } 
}
 
// Function to return the
// LCM modulo M    
public static long lcmModuloM(int[] arr,
                              int n)
{
  Dictionary maxMap =
             new Dictionary();
 
  for(int i = 0; i < n; i++)
  {
    Dictionary temp =
               new Dictionary();
    int num = arr[i];
 
    // Temp stores mapping of prime 
    // factor to its power for the
    // current element
    while(num > 1)
    {
      // Factor is the smallest
      // prime factor of num
      int factor = prime[num];
 
      if(temp.ContainsKey(factor))
        temp[factor]++;
      else
        temp.Add(factor, 1);
 
      // Factor is the smallest
      // prime factor of num    
      num = num / factor;
    }
 
    foreach(KeyValuePair m in temp)
    {
      if(maxMap.ContainsKey(m.Key))
      {
        int maxPower = Math.Max(m.Value,
                                maxMap[m.Key]);
        maxMap[m.Key] = maxPower;
      }
      else
      {
        maxMap.Add(m.Key,m.Value);
      }
    }
  }
 
  long ans = 1;
  foreach(KeyValuePair m in maxMap)
  {
    // LCM is product of primes to their
    // highest powers modulo M
    ans = (ans * power(m.Key,
                       m.Value) %
                       mod);
  }
 
  return ans;
}
 
// Driver code   
public static void Main(String[] args)
{
  sieve();
  int[] arr = new int[]{36, 500,
                        480, 343};
  int n = arr.Length;
  Console.WriteLine(lcmModuloM(arr, n));
}
}
 
// This code is contributed by 29AjayKumar


输出:
12348000




上面的代码适用于以下约束:

1 <= N <= 10^6 \newline 1 <= A[i] <= 10^7

参考文献: https : //stackoverflow.com/questions/16633449/calculate-lcm-of-n-numbers-modulo-1000000007