📜  计算 Array 中乘积可被 K 整除的对

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

计算 Array 中乘积可被 K 整除的对

给定一个数组vec和一个整数K ,计算对 (i, j) 的数量,使得vec [i]* vec [j] 可以被K整除,其中 i

例子:

朴素方法:解决这个问题最简单的方法是找到所有对,并且对于每一对,检查它们的乘积是否可以被 K 整除。

时间复杂度: O(N^2)
辅助空间: O(1)

高效方法:上述问题可以在 GCD 的帮助下高效解决。

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

  • 创建一个大小为 10^5 + 1 的计数器,以预先计算有多少数字可以被数字 num(比如说)整除(对于所有 num 1 到 10 ^ 5)。
  • 然后我们只需要循环每个元素或向量并找出需要乘以它的剩余数(remaining_factor),以使 GCD 等于 k。
  • 那么对于这个数字,对的数量将与数组中剩余因子的倍数一样多(忽略数字本身)。
  • 因此,为 vec 中的每个 i 添加对数,我们将得到我们的答案,我们将最终答案除以 2,因为我们已经对任何对 (i, j) 计算了每对两次并删除了重复项。

下面是上述方法的实现:

C++
// C++ program for Count number of pairs
// in a vector such that
// product is divisible by K
 
#include 
using namespace std;
 
// Precalculate count array to see numbers
// that are divisible by a number num (say)
// for all num 1 to 10^5
int countarr[100001];
int count_of_multiples[100001];
 
long long countPairs(vector& vec, int k)
{
    int n = vec.size();
    for (int i = 0; i < n; i++)
 
        // counting frequency of  each
        // element in vector
        countarr[vec[i]]++;
 
    for (int i = 1; i < 100001; i++) {
        for (int j = i; j < 100001; j = j + i)
 
            // counting total elements present in
            // array which are multiple of i
            count_of_multiples[i] += countarr[j];
    }
 
    long long ans = 0;
    for (int i = 0; i < n; i++) {
        long long factor = __gcd(k, vec[i]);
        long long remaining_factor = (k / factor);
        long long j = count_of_multiples[remaining_factor];
 
        // if vec[i] itself is multiple of
        // remaining factor then we to ignore
        // it as  i!=j
        if (vec[i] % remaining_factor == 0)
            j--;
        ans += j;
    }
 
    // as we have counted any distinct pair
    // (i, j) two times, we need to take them
    // only once
    ans /= 2;
 
    return ans;
}
 
// Driver code
int main()
{
    vector vec = { 1, 2, 3, 4, 5, 6 };
    int k = 4;
    cout << countPairs(vec, k) << endl;
}


Java
// Java program for Count number of pairs
// in a vector such that
// product is divisible by K
import java.util.*;
public class GFG {
 
  // Precalculate count array to see numbers
  // that are divisible by a number num (say)
  // for all num 1 to 10^5
  static int[] countarr = new int[100001];
  static int[] count_of_multiples = new int[100001];
 
  // Recursive function to return
  // gcd of a and b
  static int gcd(int a, int b)
  {
    if (b == 0)
      return a;
    return gcd(b, a % b);
  }
 
  static long countPairs(int[] vec, int k)
  {
    int n = vec.length;
    for (int i = 0; i < n; i++)
 
      // counting frequency of  each
      // element in vector
      countarr[vec[i]]++;
 
    for (int i = 1; i < 100001; i++) {
      for (int j = i; j < 100001; j = j + i)
 
        // counting total elements present in
        // array which are multiple of i
        count_of_multiples[i] += countarr[j];
    }
 
    long ans = 0;
    for (int i = 0; i < n; i++) {
      long factor = gcd(k, vec[i]);
      long remaining_factor = (k / factor);
      long j = count_of_multiples[(int)remaining_factor];
 
      // if vec[i] itself is multiple of
      // remaining factor then we to ignore
      // it as  i!=j
      if (vec[i] % remaining_factor == 0)
        j--;
      ans += j;
    }
 
    // as we have counted any distinct pair
    // (i, j) two times, we need to take them
    // only once
    ans /= 2;
 
    return ans;
  }
 
  // Driver code
  public static void main(String args[])
  {
    int[] vec = { 1, 2, 3, 4, 5, 6 };
    int k = 4;
    System.out.println(countPairs(vec, k));
  }
}
 
// This code is contributed by Samim Hossain Mondal.


Python3
# Python program for Count number of pairs
# in a vector such that
# product is divisible by K
import math
 
# Precalculate count array to see numbers
# that are divisible by a number num (say)
# for all num 1 to 10^5
countarr = [0] * 100001
count_of_multiples = [0] * 100001
 
def countPairs(vec, k):
 
    n = len(vec)
    for i in range(0, n):
 
        # counting frequency of  each
        # element in vector
        countarr[vec[i]] += 1
 
    for i in range(1, 100001):
        j = i
        while(j < 100001):
 
            # counting total elements present in
            # array which are multiple of i
            count_of_multiples[i] += countarr[j]
            j += i
 
    ans = 0
    for i in range(0, n):
        factor = math.gcd(k, vec[i])
        remaining_factor = (k // factor)
        j = count_of_multiples[remaining_factor]
 
        # if vec[i] itself is multiple of
        # remaining factor then we to ignore
        # it as  i!=j
        if (vec[i] % remaining_factor == 0):
            j -= 1
        ans += j
 
    # as we have counted any distinct pair
    # (i, j) two times, we need to take them
    # only once
    ans //= 2
    return ans
 
# Driver code
vec = [1, 2, 3, 4, 5, 6]
k = 4
print(countPairs(vec, k))
 
# This code is contributed by Samim Hossain Mondal.


C#
// C# program for Count number of pairs
// in a vector such that
// product is divisible by K
 
using System;
class GFG {
 
  // Precalculate count array to see numbers
  // that are divisible by a number num (say)
  // for all num 1 to 10^5
  static int[] countarr = new int[100001];
  static int[] count_of_multiples = new int[100001];
 
  // Recursive function to return
  // gcd of a and b
  static int gcd(int a, int b)
  {
    if (b == 0)
      return a;
    return gcd(b, a % b);
  }
 
  static long countPairs(int[] vec, int k)
  {
    int n = vec.Length;
    for (int i = 0; i < n; i++)
 
      // counting frequency of  each
      // element in vector
      countarr[vec[i]]++;
 
    for (int i = 1; i < 100001; i++) {
      for (int j = i; j < 100001; j = j + i)
 
        // counting total elements present in
        // array which are multiple of i
        count_of_multiples[i] += countarr[j];
    }
 
    long ans = 0;
    for (int i = 0; i < n; i++) {
      long factor = gcd(k, vec[i]);
      long remaining_factor = (k / factor);
      long j = count_of_multiples[remaining_factor];
 
      // if vec[i] itself is multiple of
      // remaining factor then we to ignore
      // it as  i!=j
      if (vec[i] % remaining_factor == 0)
        j--;
      ans += j;
    }
 
    // as we have counted any distinct pair
    // (i, j) two times, we need to take them
    // only once
    ans /= 2;
 
    return ans;
  }
 
  // Driver code
  public static void Main()
  {
    int[] vec = { 1, 2, 3, 4, 5, 6 };
    int k = 4;
    Console.WriteLine(countPairs(vec, k));
  }
}
 
// This code is contributed by Samim Hossain Mondal.


Javascript



输出:
6

时间复杂度: O(N*log(N))
辅助空间: O(N)