给定一个整数数组arr [] ,任务是找到该数组所有元素模L的LCM,其中M = 10 9 + 7 。
例子:
Input: arr[] = {10000000, 12345, 159873}
Output: 780789722
LCM of (10000000, 12345, 159873) is 1315754790000000
1315754790000000 % 1000000007 = 780789722
Input: arr[] = {10, 13, 15}
Output: 390
方法:如果您经过计算数组元素的LCM的文章,想到的第一种方法是在计算ans和arr [i]的LCM的每一步取模。
ans = 1
// For i = 1 to n – 1
ans = lcm(ans, arr[i]) % 1000000007 // Wrong approach
但是,这种方法是错误的,并且可以在以下示例中实现该错误:
Take M = 41 and arr[] = {13, 18, 30}
Incorrect solution:
LCM(13, 18, 30) % 41
LCM(LCM(13, 18) % 41, 30) % 41
LCM(234 % 41, 30) % 41
LCM(29, 30) % 41
870 % 41
9
Correct solution:
LCM(13, 18, 30) % 41
LCM(LCM(13, 18), 30) % 41
LCM(234, 30) % 41
1170 % 41
22
注意:每当2个数字的LCM变为> M时,该方法将不起作用。
正确的方法是对数组的元素进行质因子分解,并跟踪每个元素的每个质数的最大功效。 LCM将是这些素数提高到阵列中最高功率的产物。
插图:
Let elements be [36, 480, 500, 343]
Prime factorization results:
36 = 22 * 32
480 = 25 * 3 * 5
500 = 22 * 53
343 = 73
Highest power of 2 amongt all array elements = Max(2, 5, 2, 0) = 5
Highest power of 3 amongt all array elements = Max(2, 1, 0, 0) = 2
Highest power of 5 amongt all array elements = Max(0, 1, 3, 0) = 3
Highest power of 7 amongt all array elements = Max(0, 0, 0, 3) = 3
Therefore, LCM = 25 * 32 * 53 * 73 = 12348000
令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
上面的代码适用于以下约束:
参考文献: https : //stackoverflow.com/questions/16633449/calculate-lcm-of-n-numbers-modulo-1000000007