📌  相关文章
📜  给定数组的所有非空子序列中不同 GCD 的计数

📅  最后修改于: 2022-05-13 01:56:08.697000             🧑  作者: Mango

给定数组的所有非空子序列中不同 GCD 的计数

给定一个大小为N的整数数组arr[] ,任务是计算arr[]的所有非空子序列中不同的最大公约数 (GCD)的总数。

例子:

朴素方法:朴素方法是找到所有子序列,计算每个子序列的GCD ,最后计算不同GCD的总数。

时间复杂度: O(2 N .Log(M)),其中 M 是数组中的最大元素。

方法:可以根据以下观察解决给定的问题:

  1. 最大可能的GCD不能超过数组的最大元素(比如M )。因此,所有可能的GCD都在1M之间。
  2. 通过迭代GCD的所有可能值,即从1M ,并检查数组中是否存在i的倍数并且GCD等于i ,可以解决问题。

请按照以下步骤解决问题:

  1. 将变量ans初始化为 0。
  2. 计算arr中的最大元素并将其存储在变量中,例如M
  3. arr的所有元素存储在映射Mp中以进行恒定时间访问。
  4. 使用变量i遍历GCD的所有可能值,即从1M ,然后执行以下操作:
    • 使用变量j遍历arr中存在的M的倍数,然后执行以下操作:
    • 如果GCD在任何时候变为i ,则递增ans并中断。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to calculate the number
// of distinct GCDs among all
// non-empty subsequences of an array
int distinctGCDs(int arr[], int N)
{
    // variables to store the largest element
// in array and the required count
    int M = -1, ans = 0;
 
    // Map to store whether
// a number is present in A
    map Mp;
 
    // calculate largest number
// in A and mapping A to Mp
    for (int i = 0; i < N; i++) {
        M = max(M, arr[i]);
        Mp[arr[i]] = 1;
    }
 
    // iterate over all possible values of GCD
    for (int i = 1; i <= M; i++) {
 
        // variable to check current GCD
        int currGcd = 0;
 
        // iterate over all multiples of i
        for (int j = i; j <= M; j += i) {
 
            // If j is present in A
            if (Mp[j]) {
 
                // calculate gcd of all encountered
                // multiples of i
                currGcd = __gcd(currGcd, j);
 
                // current GCD is possible
                if (currGcd == i) {
                    ans++;
                    break;
                }
            }
        }
    }
    // return answer
    return ans;
}
// Driver code
int main()
{
    // Input
    int arr[] = { 3, 11, 14, 6, 12 };
    int N = sizeof(arr) / sizeof(arr[0]);
 
    // Function calling
    cout << distinctGCDs(arr, N) << endl;
 
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
 
class GFG{
 
static int gcd(int a, int b)
{
    return b == 0 ? a : gcd(b, a % b);
}
 
// Function to calculate the number
// of distinct GCDs among all
// non-empty subsequences of an array
static int distinctGCDs(int []arr, int N)
{
     
    // Variables to store the largest element
    // in array and the required count
    int M = -1, ans = 0;
     
    // Map to store whether
    // a number is present in A
    HashMap Mp = new HashMap();
     
    // Calculate largest number
    // in A and mapping A to Mp
    for(int i = 0; i < N; i++)
    {
        M = Math.max(M, arr[i]);
         
        if (Mp.containsKey(arr[i]))
            Mp.put(arr[i],1);
        else
            Mp.put(arr[i],0);
    }
     
    // Iterate over all possible values of GCD
    for(int i = 1; i <= M; i++)
    {
     
        // Variable to check current GCD
        int currGcd = 0;
         
        // Iterate over all multiples of i
        for(int j = i; j <= M; j += i)
        {
         
            // If j is present in A
            if (Mp.containsKey(j))
            {
             
                // Calculate gcd of all encountered
                // multiples of i
                currGcd = gcd(currGcd, j);
                 
                // Current GCD is possible
                if (currGcd == i)
                {
                    ans++;
                    break;
                }
            }
        }
    }
     
    // Return answer
    return ans;
}
 
// Driver code
public static void main(String [] args)
{
     
    // Input
    int []arr = { 3, 11, 14, 6, 12 };
    int N = arr.length;
 
    // Function calling
    System.out.println(distinctGCDs(arr, N));
}
}
 
// This code is contributed by ukasp.


Python3
# Python 3 program for the above approach
from math import gcd
 
# Function to calculate the number
# of distinct GCDs among all
# non-empty subsequences of an array
def distinctGCDs(arr, N):
   
    # variables to store the largest element
    # in array and the required count
    M = -1
    ans = 0
 
    # Map to store whether
    # a number is present in A
    Mp = {}
 
    # calculate largest number
    # in A and mapping A to Mp
    for i in range(N):
        M = max(M, arr[i])
        Mp[arr[i]] = 1
 
    # iterate over all possible values of GCD
    for i in range(1, M + 1, 1):
       
        # variable to check current GCD
        currGcd = 0
 
        # iterate over all multiples of i
        for j in range(i, M + 1, i):
           
            # If j is present in A
            if (j in Mp):
               
                # calculate gcd of all encountered
                # multiples of i
                currGcd = gcd(currGcd, j)
 
                # current GCD is possible
                if (currGcd == i):
                    ans += 1
                    break
 
    # return answer
    return ans
 
# Driver code
if __name__ == '__main__':
    # Input
    arr = [3, 11, 14, 6, 12]
    N = len(arr)
 
    # Function calling
    print(distinctGCDs(arr, N))
     
    # This code is contributed by bgangwar59.


C#
// C# program for the above approach
using System;
using System.Collections.Generic;
 
class GFG{
 
static int gcd(int a, int b)
{
    return b == 0 ? a : gcd(b, a % b);
}
 
// Function to calculate the number
// of distinct GCDs among all
// non-empty subsequences of an array
static int distinctGCDs(int []arr, int N)
{
     
    // Variables to store the largest element
    // in array and the required count
    int M = -1, ans = 0;
     
    // Map to store whether
    // a number is present in A
    Dictionary Mp = new Dictionary();
     
    // Calculate largest number
    // in A and mapping A to Mp
    for(int i = 0; i < N; i++)
    {
        M = Math.Max(M, arr[i]);
         
        if (Mp.ContainsKey(arr[i]))
            Mp[arr[i]] = 1;
        else
            Mp.Add(arr[i],1);
    }
     
    // Iterate over all possible values of GCD
    for(int i = 1; i <= M; i++)
    {
     
        // Variable to check current GCD
        int currGcd = 0;
         
        // Iterate over all multiples of i
        for(int j = i; j <= M; j += i)
        {
         
            // If j is present in A
            if (Mp.ContainsKey(j))
            {
             
                // Calculate gcd of all encountered
                // multiples of i
                currGcd = gcd(currGcd, j);
                 
                // Current GCD is possible
                if (currGcd == i)
                {
                    ans++;
                    break;
                }
            }
        }
    }
     
    // Return answer
    return ans;
}
 
// Driver code
public static void Main()
{
     
    // Input
    int []arr = { 3, 11, 14, 6, 12 };
    int N = arr.Length;
 
    // Function calling
    Console.Write(distinctGCDs(arr, N));
}
}
 
// This code is contributed by ipg2016107


Javascript


输出
7

时间复杂度: O(M*log(M)),其中 M 是数组中的最大元素
辅助空间: O(M)