📜  查找数组中所有唯一对的LCM的GCD

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

给定一个大小为N的整数数组arr [] ,任务是找到该数组所有唯一对(i,j)的LCM的GCD,以使i
例子:

天真的方法:最简单的方法是查找数组中的所有唯一对。然后找到他们的LCM。然后找到所有LCM的GCD。

高效的方法:可以通过后缀数组来优化上述幼稚的方法。我们可以使用后缀数组来高效地找到每个元素与其他元素配对的LCM。然后,我们可以简单地找到并返回此LCM阵列的GCD。

  • 对于每个元素A [i],我们需要计算LCM(a [i],a [j]) ,其中j属于[i + 1,N-1]。
  • 起始元素为A [i]的所有对的LCM可以写成
  • 为此,我们构建了一个后缀数组。假设suffix []存储了属于[i + 1,N-1]范围的元素的gcd。
  • 然后创建一个LCM数组来存储A [i]的LCM和其后所有元素的GCD,即
  • 最后,计算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)