Count pairs whose product modulo 10^9 + 7 is equal to 1
Last Updated :
09 Dec, 2022
Given an array arr[], the task is to count the number of unordered pairs (arr[i], arr[j]) from the given array such that (arr[i] * arr[j]) % 109 + 7 is equal to 1.
Example:
Input: arr[] = {2, 236426, 280311812, 500000004}
Output: 2
Explanation: Two such pairs from the given array are:
- (2 * 500000004) % 1000000007 = 1
- (236426 * 280311812) % 1000000007 = 1
Input: arr[] = {4434, 923094278, 6565}
Output: 1
Naive Approach: The simplest approach to solve the problem is to traverse the array and generate all possible pairs from the given array. For each pair, calculate their product modulo 109 + 7. If it is found to be equal to 1, increase count of such pairs. Finally, print the final count obtained.
Time Complexity: O(N2)
Auxiliary Space: O(N)
Efficient Approach: To optimize the above approach, use the property that if (arr[i] * arr[j]) % 1000000007 =1, then arr[j] is modular inverse of arr[i] under modulo 109 + 7 which is always unique. Follow the steps given below to solve the problem:
- Initialize a Map hash, to store the frequencies of each element in the array arr[].
- Initialize a variable pairCount, to store the count of required pairs.
- Traverse the array and calculate modularInverse which is inverse of arr[i] under 109 + 7 and increase pairCount by hash[modularInverse] and decrease the count of pairCount by 1, if modularInverse is found to be equal to arr[i].
- Finally, print pairCount / 2 as the required answer as every pair has been counted twice by the above approach.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
#define MOD 1000000007
long long int modPower( long long int x,
long long int y)
{
long long int res = 1;
x = x % MOD;
if (x == 0)
return 0;
while (y > 0) {
if (y & 1)
res = (res * x) % MOD;
y = y / 2;
x = (x * x) % MOD;
}
return res;
}
int countPairs( long long int arr[], int N)
{
int pairCount = 0;
map< long long int , int > hash;
for ( int i = 0; i < N; i++) {
hash[arr[i]]++;
}
for ( int i = 0; i < N; i++) {
long long int modularInverse
= modPower(arr[i], MOD - 2);
pairCount += hash[modularInverse];
if (arr[i] == modularInverse) {
pairCount--;
}
}
return pairCount / 2;
}
int main()
{
long long int arr[]
= { 2, 236426, 280311812, 500000004 };
int N = sizeof (arr) / sizeof (arr[0]);
cout << countPairs(arr, N);
return 0;
}
|
Java
import java.util.*;
class GFG{
static final int MOD = 1000000007 ;
static long modPower( long x, int y)
{
long res = 1 ;
x = x % MOD;
if (x == 0 )
return 0 ;
while (y > 0 )
{
if (y % 2 == 1 )
res = (res * x) % MOD;
y = y / 2 ;
x = (x * x) % MOD;
}
return res;
}
static int countPairs( long arr[], int N)
{
int pairCount = 0 ;
HashMap<Long, Integer> hash = new HashMap<>();
for ( int i = 0 ; i < N; i++)
{
if (hash.containsKey(arr[i]))
{
hash.put(arr[i], hash.get(arr[i]) + 1 );
}
else
{
hash.put(arr[i], 1 );
}
}
for ( int i = 0 ; i < N; i++)
{
long modularInverse = modPower(arr[i],
MOD - 2 );
if (hash.containsKey(modularInverse))
pairCount += hash.get(modularInverse);
if (arr[i] == modularInverse)
{
pairCount--;
}
}
return pairCount / 2 ;
}
public static void main(String[] args)
{
long arr[] = { 2 , 236426 , 280311812 , 500000004 };
int N = arr.length;
System.out.print(countPairs(arr, N));
}
}
|
Python3
from collections import defaultdict
MOD = 1000000007
def modPower(x, y):
res = 1
x = x % MOD
if (x = = 0 ):
return 0
while (y > 0 ):
if (y & 1 ):
res = (res * x) % MOD
y = y / / 2
x = (x * x) % MOD
return res
def countPairs(arr, N):
pairCount = 0
hash1 = defaultdict( int )
for i in range (N):
hash1[arr[i]] + = 1
for i in range (N):
modularInverse = modPower(arr[i],
MOD - 2 )
pairCount + = hash1[modularInverse]
if (arr[i] = = modularInverse):
pairCount - = 1
return pairCount / / 2
if __name__ = = "__main__" :
arr = [ 2 , 236426 ,
280311812 ,
500000004 ]
N = len (arr)
print (countPairs(arr, N))
|
C#
using System;
using System.Collections.Generic;
class GFG{
static int MOD = 1000000007;
static long modPower( long x, int y)
{
long res = 1;
x = x % MOD;
if (x == 0)
return 0;
while (y > 0)
{
if (y % 2 == 1)
res = (res * x) % MOD;
y = y / 2;
x = (x * x) % MOD;
}
return res;
}
static int countPairs( long []arr, int N)
{
int pairCount = 0;
Dictionary< long ,
int > hash = new Dictionary< long ,
int >();
for ( int i = 0; i < N; i++)
{
if (hash.ContainsKey(arr[i]))
{
hash.Add(arr[i], hash[arr[i]] + 1);
}
else
{
hash.Add(arr[i], 1);
}
}
for ( int i = 0; i < N; i++)
{
long modularInverse = modPower(arr[i],
MOD - 2);
if (hash.ContainsKey(modularInverse))
pairCount += hash[modularInverse];
if (arr[i] == modularInverse)
{
pairCount--;
}
}
return pairCount / 2;
}
public static void Main()
{
long []arr = { 2, 236426, 280311812, 500000004 };
int N = arr.Length;
Console.WriteLine(countPairs(arr, N));
}
}
|
Javascript
let MOD = 1000000007
function modPower(x, y)
{
let res = 1
x = x % MOD
if (x == 0)
return 0
while (y > 0)
{
if ((y & 1) == 1)
res = (res * x) % MOD
y = Math.floor(y / 2)
x = (x * x) % MOD
}
return res
}
function countPairs(arr, N)
{
let pairCount = 0
hash1 = {}
for ( var i = 0; i < N; i++)
{
if (!hash1.hasOwnProperty(arr[i]))
hash1[arr[i]] = 0
hash1[arr[i]] += 1
}
for ( var i = 0; i < N; i++)
{
let modularInverse = modPower(arr[i], MOD - 2)
if (!hash1.hasOwnProperty(modularInverse))
hash1[modularInverse] = 1
pairCount += hash1[modularInverse]
if (arr[i] == modularInverse)
pairCount -= 1
}
return Math.floor(pairCount / 2)
}
let arr = [2, 236426,
280311812,
500000004]
let N = arr.length
console.log(countPairs(arr, N))
|
Time Complexity: O(NlogN)
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...