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)
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
09 Dec, 2022
Like Article
Save Article