给定数组的所有非空子序列中不同 GCD 的计数
给定一个大小为N的整数数组arr[] ,任务是计算arr[]的所有非空子序列中不同的最大公约数 (GCD)的总数。
例子:
Input: arr[]={3,4,8} N=3
Output:
4
Explanation:
The different non-empty subsequences possible are {3}, {4}, {8}, {3,4}, {4,8}, {3,8}, {3,4,8} and their corresponding GCDs are 3,4,8,1,4,1,1.
Thus, the total number of distinct GCDs is 4 (1,3,4,8).
Input: arr[]={3,11,14,6,12}, N=5
Output:
7
朴素方法:朴素方法是找到所有子序列,计算每个子序列的GCD ,最后计算不同GCD的总数。
时间复杂度: O(2 N .Log(M)),其中 M 是数组中的最大元素。
方法:可以根据以下观察解决给定的问题:
- 最大可能的GCD不能超过数组的最大元素(比如M )。因此,所有可能的GCD都在1到M之间。
- 通过迭代GCD的所有可能值,即从1到M ,并检查数组中是否存在i的倍数并且GCD等于i ,可以解决问题。
请按照以下步骤解决问题:
- 将变量ans初始化为 0。
- 计算arr中的最大元素并将其存储在变量中,例如M 。
- 将arr的所有元素存储在映射Mp中以进行恒定时间访问。
- 使用变量i遍历GCD的所有可能值,即从1到M ,然后执行以下操作:
- 使用变量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)