给定一个大小为N的整数数组arr[] ,任务是找到数组中所有唯一对(i, j)的 LCM 的 GCD,使得i < j 。
例子:
Input: arr[] = {10, 24, 40, 80}
Output: 40
Explanation:
LCM of all unique pairs following given conditions are:
LCM(10, 24) = 120
LCM(10, 40) = 40
LCM(10, 80) = 80
LCM(24, 40) = 120
LCM(24, 80) = 240
LCM(40, 80) = 80
Therefore, GCD of these LCM = GCD(120, 40, 80, 120, 240, 80) = 40
Input: arr[] = {1, 1}
Output: 1
朴素的方法:最简单的方法是找到数组中所有唯一的对。然后找到他们的LCM。然后找到所有LCM的GCD。
高效的方法:可以在后缀数组的帮助下优化上述朴素的方法。我们可以使用后缀数组高效地找到与其他元素配对的每个元素的 LCM。然后我们可以简单地找到并返回这个 LCM 数组的 GCD。
- 对于每个元素 A[i],我们需要计算LCM(a[i], a[j]) ,其中 j 属于 [i+1, N-1]。
- 起始元素为 A[i] 的所有对的 LCM 可以写为
LCM(A[i], GCD(all j in range i+1 to n-1))
- 为此,我们构建了一个后缀数组。假设suffix[]存储属于范围[i+1, N-1]的元素的 gcd 。
- 然后创建一个LCM数组来存储A[i]的LCM和其后所有元素的GCD,即
LCM[i] = LCM(A[i], suffix[i+1])
Where suffix[i+1] stores the GCD of elements [i+1, n-1]
- 最后计算 LCM 数组中所有元素的 GCD。
C++
// C++ code to find the GCD of LCM
// of all unique pairs in an Array
#include
using namespace std;
// Find lcm of element x and y
int LCM(int x, int y)
{
return x * y / __gcd(x, y);
}
// Function that finds gcd of lcm
// of all pairs of elements.
void gcd_of_lcm(int n, int arr[])
{
// n is the size of the array.
// arr is the array.
// Suffix array that stores
// the gcd of the array elements.
int suff[n];
// Initialize suffix array.
for(int x = 0; x < n; x++)
{
suff[x] = 1;
}
// Loop that make the suffix gcd array
suff[n - 1] = arr[n - 1];
for(int i = n - 2; i >= 0; i--)
{
suff[i] = __gcd(arr[i], suff[i + 1]);
}
// lcm array that store the lcm
// of ith elements for all j
// that satisfy given condition.
vector lcm;
for(int i = 0; i < n - 1; i++)
{
// we find lcm[i] for lcm
// of ith elements for all j
// using bellow formula.
int y = LCM(arr[i], suff[i + 1]);
// Add lcm of ith elements
// for all j in lcm array.
lcm.push_back(y);
}
// Now we find gcd of all ith elements.
// where i = 0, 1, 2, 3.....n-2.
int ans = lcm[0];
for(int i = 1; i < n - 1; i++)
{
ans = __gcd(ans, lcm[i]);
}
cout << ans << endl;
}
// Driver code
int main()
{
int n = 4;
int a[] = { 10, 24, 40, 80 };
// Function call for input 1
gcd_of_lcm(n, a);
n = 10;
int b[] = { 540, 648, 810, 648, 720,
540, 594, 864, 972, 648 };
// Function call for input 2
gcd_of_lcm(n, b);
}
// This code is contributed by shobhitgupta907
Java
// Java code to find the GCD of LCM
// of all unique pairs in an array
class GFG{
// Function to evaluate GCD of x and y
static int gcd(int x, int y)
{
if (y == 0)
return x;
else
return gcd(y, x % y);
}
// Function that finds gcd of lcm
// of all pairs of elements.
static void gcd_of_lcm(int n, int arr[])
{
// n = size of array i.e. arr[]
// Suffix array that stores
// the GCD of the array elements.
int suff[] = new int[n];
// Initialise the suffix array
for(int i = 0; i < n; i++)
suff[i] = 1;
// Loop that make suffix GCD array
suff[n - 1] = arr[n - 1];
for(int i = n - 2; i >= 0; i--)
suff[i] = gcd(arr[i], suff[i + 1]);
// lcm array that store lcm for pairwise
// consecutive elements
int lcm[] = new int[n - 1];
for(int i = 0; i < n - 1; i++)
// Find LCM using standard known formula
lcm[i] = (arr[i] * suff[i + 1]) /
gcd(arr[i], suff[i + 1]);
// Now we find gcd of all ith elements.
// where i = 0, 1, 2, 3.....n-2.
int ans = lcm[0];
for(int i = 1; i < n - 1; i++)
{
ans = gcd(ans, lcm[i]);
}
// Print the answer
System.out.println(ans);
}
// Driver code
public static void main(String[] args)
{
// 1st input case
int n = 4;
int a[] = { 10, 24, 40, 80 };
// Function call for input 1
gcd_of_lcm(n, a);
// 2nd input case
n = 10;
int b[] = { 540, 648, 810, 648, 720,
540, 594, 864, 972, 648 };
// Function call for input 2
gcd_of_lcm(n, b);
}
}
// This code is contributed by Soumitri Chattopadhyay
Python3
# Python3 code to find the GCD of LCM
# of all unique pairs in an Array
from math import gcd
# find lcm of element x and y
def LCM(x, y):
return (x * y)//gcd(x, y)
# Function that finds gcd of lcm
# of all pairs of elements.
def gcd_of_lcm(n, arr):
# n is the size of the array.
# arr is the array.
# suffix array that stores
# the gcd of the array elements.
suff = [1]*n
# initialize suffix array.
# loop that make the suffix gcd array.
suff[n-1] = arr[n-1]
for i in range(n-2, -1, -1):
suff[i] = gcd(arr[i], suff[i + 1])
# lcm array that store the lcm
# of ith elements for all j
# that satisfy given condition.
lcm = []
for i in range(n-1):
# we find lcm[i] for lcm
# of ith elements for all j
# using bellow formula.
y = LCM( arr[i], suff[i + 1])
# add lcm of ith elements
# for all j in lcm array.
lcm.append(y)
# now we find gcd of all ith elements.
# where i = 0, 1, 2, 3.....n-2.
ans = lcm[0]
for i in range(1, n-1):
ans = gcd(ans, lcm[i])
print(ans)
if __name__== "__main__":
n = 4
a =[10, 24, 40, 80]
# function call for input 1
gcd_of_lcm(n, a)
n = 10
a =[540, 648, 810, 648, 720,
540, 594, 864, 972, 648]
# function call for input 2
gcd_of_lcm(n, a)
C#
// C# code to find the GCD of LCM
// of all unique pairs in an array
using System;
class GFG{
// Function to evaluate GCD of x and y
static int gcd(int x, int y)
{
if (y == 0)
return x;
else
return gcd(y, x % y);
}
// Function that finds gcd of lcm
// of all pairs of elements.
static void gcd_of_lcm(int n, int[] arr)
{
// n = size of array i.e. arr[]
// Suffix array that stores
// the GCD of the array elements.
int[] suff = new int[n];
// Initialise the suffix array
for(int i = 0; i < n; i++)
suff[i] = 1;
// Loop that make suffix GCD array
suff[n - 1] = arr[n - 1];
for(int i = n - 2; i >= 0; i--)
suff[i] = gcd(arr[i], suff[i + 1]);
// lcm array that store lcm for pairwise
// consecutive elements
int[] lcm = new int[n - 1];
for(int i = 0; i < n - 1; i++)
// Find LCM using standard known formula
lcm[i] = (arr[i] * suff[i + 1]) /
gcd(arr[i], suff[i + 1]);
// Now we find gcd of all ith elements.
// where i = 0, 1, 2, 3.....n-2.
int ans = lcm[0];
for(int i = 1; i < n - 1; i++)
{
ans = gcd(ans, lcm[i]);
}
// Print the answer
Console.WriteLine(ans);
}
// Driver code
public static void Main()
{
// 1st input case
int n = 4;
int[] a = { 10, 24, 40, 80 };
// Function call for input 1
gcd_of_lcm(n, a);
// 2nd input case
n = 10;
int[] b = { 540, 648, 810, 648, 720,
540, 594, 864, 972, 648 };
// Function call for input 2
gcd_of_lcm(n, b);
}
}
// This code is contributed by sanjoy_62
Javascript
40
54
时间复杂度: O(N * log M) ,其中 M 是数组中的最大元素。
空间复杂度: O(N)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live