Last Updated: 15 May, 2022

Pair Product Div by K

Moderate
Asked in companies
AmazonWalmart

Problem statement

Given a integer array nums of length ‘N’ and an integer ‘K’, return the number of pairs ‘(i, j)’ such that:

1 <= ‘i’ < ‘j’ <= ‘N’ and ‘nums[i] * nums[j]’ is divisible by ‘K’.

EXAMPLE :
‘N’ = 5, ‘K’ = 4, ‘nums’ = [2, 6, 1, 7, 8]
Output: 5
Explanation: (1, 2), (1, 5), (2, 5), (3, 5), and (4, 5) pairs have their products divisible by K.
Input Format :
The first line will contain the integer 'T', the number of test cases.

Each test case consists of two lines.

The first input line contains two integers, 'N' and 'K', separated by spaces.

Followed by a line containing space-separated ‘N’ positive integers, denoting the array nums.
Output format :
For each test case, print the count of unique pairs having their product divisible by ‘K’.
Note :
You don't need to print anything. It has already been taken care of. Just implement the given function.
Constraints :
1 <= 'T' <= 10
1 <= 'N' <= 10^5
1 <= 'K' <= 10^5
1 <= ‘nums[i]’ <= 10^6
It is guaranteed that sum of ‘N’ over all test cases is <= 10^5
Time Limit: 1 sec

Approaches

01 Approach

The idea is to iterate over all possible pairs and check if their product is divisible by ‘K’ or not.
 

If it is divisible by ‘K’ we will increment our answer count by one. Initially, its value will be zero.
 

Here the number of pairs can exceed the 32-bit integer type; hence we will use the 64-bit integer type to store the answer.
 

Algorithm:
 

// This function will iterate through every possible pair which can be formed using a given array ‘nums’ of length ‘N’ and return the count of pairs whose product is divisible by ‘K’.

Int pairProductDivByK(N, K, nums) 

  • Initialize variable named ‘ans’ with value 0.
  • Run a loop from 0 to ‘N-1’ with a variable ‘i’
    • Run a loop from 0 to ‘i-1’ with a variable ‘j’
      • If ‘nums[i] * nums[j] % K == 0’ increment ‘ans’ by one
  • Return ‘ans’

02 Approach

A number with a factor ‘x’ will form a pair with a number with a factor ‘y’ if ‘x * y’ is divisible by ‘K’.
 

It can be shown that if ‘nums[i] * nums[j] % K == 0’, then ‘gcd(nums[i], K) * gcd(nums[j], K) % K == 0’.
 

Proof: 
 

  • Hopefully, you can see this intuitively. When a number is divisible by another number, its prime factorization is a superset of the prime factorization of that number.
     
  • For example, 5544 (2 * 2 * 2 * 3 * 3 * 7 * 11) is divisible by 84 (2 * 2 * 3 * 7).
  • GCD is an intersection between prime factorizations of two numbers. So, when we do ‘gcd(nums[i], K)’, we remove all prime factors from ‘nums[i]’ that do not exist in ‘K’ and therefore do not matter for divisibility.
     
  • For example, GCD of 198 (2 * 3 * 3 * 11) and 84 (2 * 2 * 3 * 7) is 6 (2 * 3).
  • With that, we can see that gcd(gcd(nums[i], K) * gcd(nums[j], K), K) = gcd(nums[i] * nums[j], K). For example:
    • gcd(gcd(198, 84) * gcd(28, 84), 84) = gcd((2 * 3) * (2 * 2 * 7), 2 * 2 * 3 * 7) = 2 * 2 * 3 * 7.
    • gcd(198 * 28, 84) = gcd((2 * 3 * 3 * 11) * (2 * 2 * 7), 2 * 2 * 3 * 7) = 2 * 2 * 3 * 7.
       

Here GCD/gcd means the Greatest Common Divisor of the two numbers.
 

So The whole idea is to break down (factorize) the numbers and multiply them with the required factors so that their overall product is divisible by K.

 

We can do this using Hash Map.
 

So firstly, we will iterate on the given array and insert all the ‘gcd(nums[i], K)’ in the map.

Then we will iterate on the map and find all the pairs having ‘gcd(nums[i], K) * gcd(nums[j],K) % K == 0’. As the max number of factors for a given K <= 10^6, is 240, our solution will fit in the time limit.
 

Here the number of pairs can exceed the 32-bit integer type; hence we will use the 64-bit integer type to store the answer.
 

Algorithm:
 

// This function will iterate through every possible pair which can be formed using a given array and return the count of pairs whose product is divisible by ‘K’.

Int pairProductDivByK(n, k, nums)

  • Initialize variable named ‘ans’ with value 0.
  • Initialize a Hash Map with the name ‘factorCount’.
  • Run a loop from 0 to ‘N-1’ with a variable ‘i’
    • Initialize variable named ‘currFactor’ with value ‘gcd(nums[i], K)’.
    • Increment the value of key ‘currFactor’ in ‘factorCount’ map by one.
  • Initialize an array of pairs named ‘factorCountArr’
  • Iterate on the map ‘factorCount’ with a variable ‘it’
    • Append ‘it’ to ‘factorCountArr’
  • Initialize a variable ‘size’ with the value of the length of the array ‘factorCountArr’
  • Run a loop from 0 to ‘size - 1’ with a variable ‘i’
    • Run a loop from ‘i+1’ to ‘size-1’ with a variable name ‘j’
      • If ‘factorCountArr[i].first * factorCountArr[j].first % K == 0’
        • Add ‘factorCountArr[i].second * factorCountArr[j].second’ to ‘ans’
    • If ‘factorCountArr[i].first * factorCountArr[i].first % K == 0’
      • Initiliaze variable named ‘cnt’ with value ‘factorCountArr[i].second’
      • Add ‘cnt * (cnt - 1) / 2’ to ‘ans’
  • Return ‘ans’