Given an array of integers arr[0..n-1], count all pairs (arr[i], arr[j]) in the such that i*arr[i] > j*arr[j], 0 =< i < j < n.
Examples :
Input : arr[] = {5 , 0, 10, 2, 4, 1, 6} Output: 5 Pairs which hold condition i*arr[i] > j*arr[j] are (10, 2) (10, 4) (10, 1) (2, 1) (4, 1) Input : arr[] = {8, 4, 2, 1} Output : 2
A Simple solution is to run two loops. Pick each element of the array one by one and for each element find an element on the right side of the array that holds the condition, then increment the counter, and last return the counter value.
Below is the implementation of the above idea:
// C++ program to count all pair that // hold condition i*arr[i] > j*arr[j] #include<iostream> using namespace std;
// Return count of pair in given array // such that i*arr[i] > j*arr[j] int CountPair( int arr[] , int n )
{ int result = 0; // Initialize result
for ( int i=0; i<n; i++)
{
// Generate all pair and increment
// counter if the hold given condition
for ( int j = i + 1; j < n; j++)
if (i*arr[i] > j*arr[j] )
result ++;
}
return result;
} // Driver code int main()
{ int arr[] = {5 , 0, 10, 2, 4, 1, 6} ;
int n = sizeof (arr)/ sizeof (arr[0]);
cout << "Count of Pairs : "
<< CountPair(arr, n);
return 0;
} |
// Java Code for Count pairs in an // array that hold i*arr[i] > j*arr[j] class GFG {
// Return count of pair in given array
// such that i*arr[i] > j*arr[j]
public static int CountPair( int arr[] , int n )
{
int result = 0 ; // Initialize result
for ( int i = 0 ; i < n; i++)
{
// Generate all pair and increment
// counter if the hold given condition
for ( int j = i + 1 ; j < n; j++)
if (i*arr[i] > j*arr[j] )
result ++;
}
return result;
}
/* Driver program to test above function */
public static void main(String[] args)
{
int arr[] = { 5 , 0 , 10 , 2 , 4 , 1 , 6 } ;
int n = arr.length;
System.out.println( "Count of Pairs : " +
CountPair(arr, n));
}
}
// This code is contributed by Arnav Kr. Mandal. |
# Python3 Code to Count pairs in an # array that hold i*arr[i] > j*arr[j] # Return count of pair in given array # such that i*arr[i] > j*arr[j] def CountPair(arr , n ):
# Initialize result
result = 0 ;
for i in range ( 0 , n):
# Generate all pair and increment
# counter if the hold given condition
j = i + 1
while (j < n):
if (i * arr[i] > j * arr[j] ):
result = result + 1
j = j + 1
return result;
# Driver program to test above function */ arr = [ 5 , 0 , 10 , 2 , 4 , 1 , 6 ]
n = len (arr)
print ( "Count of Pairs : " , CountPair(arr, n))
# This code is contributed by Sam007. |
// C# Code to Count pairs in an // array that hold i*arr[i] > j*arr[j] using System;
class GFG
{ // Return count of pair in given array
// such that i*arr[i] > j*arr[j]
public static int CountPair( int []arr , int n )
{
// Initialize result
int result = 0;
for ( int i = 0; i < n; i++)
{
// Generate all pair and increment
// counter if the hold given condition
for ( int j = i + 1; j < n; j++)
if (i*arr[i] > j*arr[j] )
result ++;
}
return result;
}
/* Driver program to test above function */
public static void Main()
{
int []arr = {5, 0, 10, 2, 4, 1, 6};
int n = arr.Length;
Console.WriteLine( "Count of Pairs : " +
CountPair(arr, n));
}
} // This code is contributed by Sam007 |
<?php // PHP program to count all pair that // hold condition i*arr[i] > j*arr[j] // Return count of pair in given array // such that i*arr[i] > j*arr[j] function CountPair( $arr , $n )
{ // Initialize result
$result = 0;
for ( $i = 0; $i < $n ; $i ++)
{
// Generate all pair and increment
// counter if the hold given condition
for ( $j = $i + 1; $j < $n ; $j ++)
if ( $i * $arr [ $i ] > $j * $arr [ $j ] )
$result ++;
}
return $result ;
} // Driver code
$arr = array (5, 0, 10, 2, 4, 1, 6) ;
$n = sizeof( $arr );
echo "Count of Pairs : " ,
CountPair( $arr , $n );
// This code is contributed by m_kit ?> |
<script> // JavaScript program to Count pairs in an // array that hold i*arr[i] > j*arr[j] // Return count of pair in given array // such that i*arr[i] > j*arr[j] function CountPair(arr, n)
{ // Initialize result
let result = 0;
for (let i = 0; i < n; i++)
{
// Generate all pair and increment
// counter if the hold given condition
for (let j = i + 1; j < n; j++)
if (i * arr[i] > j * arr[j] )
result ++;
}
return result;
} // Driver Code let arr = [5 , 0, 10, 2, 4, 1, 6] ; let n = arr.length; document.write( "Count of Pairs : " +
CountPair(arr, n));
// This code is contributed by souravghosh0416 </script> |
Count of Pairs : 5
Time Complexity: O(n2)
Auxiliary Space: O(1)
An efficient solution to this problem takes O(n log n) time. The idea is based on an interesting fact about this problem after modifying the array such that every element is multiplied by its index, this problem converts into Count Inversions in an array.
Algorithm :
Given an array ‘arr’ and it’s size ‘n’
- First traversal array element, i goes from 0 to n-1
- Multiple each element with its index arr[i] = arr[i] * i
- After that step 1. whole process is similar to Count Inversions in an array.
Below is the implementation of the above idea
// C++ program to count all pair that // hold condition i*arr[i] > j*arr[j] #include <bits/stdc++.h> using namespace std;
/* This function merges two sorted arrays and returns inversion count in the arrays.*/
int merge( int arr[], int temp[], int left,
int mid, int right)
{ int inv_count = 0;
int i = left; /* index for left subarray*/
int j = mid; /* index for right subarray*/
int k = left; /* index for resultant subarray*/
while ((i <= mid - 1) && (j <= right))
{
if (arr[i] <= arr[j])
temp[k++] = arr[i++];
else
{
temp[k++] = arr[j++];
inv_count = inv_count + (mid - i);
}
}
/* Copy the remaining elements of left
subarray (if there are any) to temp*/
while (i <= mid - 1)
temp[k++] = arr[i++];
/* Copy the remaining elements of right
subarray (if there are any) to temp*/
while (j <= right)
temp[k++] = arr[j++];
/* Copy back the merged elements to original
array*/
for (i=left; i <= right; i++)
arr[i] = temp[i];
return inv_count;
} /* An auxiliary recursive function that sorts the input array and returns the number of
inversions in the array. */
int _mergeSort( int arr[], int temp[], int left,
int right)
{ int mid, inv_count = 0;
if (right > left)
{
/* Divide the array into two parts and call
_mergeSortAndCountInv() for each of
the parts */
mid = (right + left)/2;
/* Inversion count will be sum of inversions in
left-part, right-part and number of inversions
in merging */
inv_count = _mergeSort(arr, temp, left, mid);
inv_count += _mergeSort(arr, temp, mid+1, right);
/*Merge the two parts*/
inv_count += merge(arr, temp, left, mid+1, right);
}
return inv_count;
} /* This function sorts the input array and returns the number of inversions in the
array */
int countPairs( int arr[], int n)
{ // Modify the array so that problem reduces to
// count inversion problem.
for ( int i=0; i<n; i++)
arr[i] = i*arr[i];
// Count inversions using same logic as
// below post
int temp[n];
return _mergeSort(arr, temp, 0, n - 1);
} // Driver code int main()
{ int arr[] = {5, 0, 10, 2, 4, 1, 6};
int n = sizeof (arr)/ sizeof (arr[0]);
cout << "Count of Pairs : "
<< countPairs(arr, n);
return 0;
} |
// Java program to count all pair that // hold condition i*arr[i] > j*arr[j] import java.io.*;
class GFG
{ // This function merges two sorted arrays and
// returns inversion count in the arrays.
static int merge( int arr[], int temp[], int left,
int mid, int right)
{
int inv_count = 0 ;
/* index for left subarray*/
int i = left;
/* index for right subarray*/
int j = mid;
/* index for resultant subarray*/
int k = left;
while ((i <= mid - 1 ) && (j <= right))
{
if (arr[i] <= arr[j])
temp[k++] = arr[i++];
else
{
temp[k++] = arr[j++];
inv_count = inv_count + (mid - i);
}
}
/* Copy the remaining elements of left
subarray (if there are any) to temp*/
while (i <= mid - 1 )
temp[k++] = arr[i++];
/* Copy the remaining elements of right
subarray (if there are any) to temp*/
while (j <= right)
temp[k++] = arr[j++];
// Copy back the merged elements
// to original array
for (i = left; i <= right; i++)
arr[i] = temp[i];
return inv_count;
}
/* An auxiliary recursive function
that sorts the input array and
returns the number of inversions
in the array. */
static int _mergeSort( int arr[], int temp[],
int left, int right)
{
int mid, inv_count = 0 ;
if (right > left)
{
/* Divide the array into two parts and call
_mergeSortAndCountInv() for each of
the parts */
mid = (right + left) / 2 ;
// Inversion count will be sum of inversions in
// left-part, right-part and number of inversions
// in merging
inv_count = _mergeSort(arr, temp, left, mid);
inv_count += _mergeSort(arr, temp, mid+ 1 , right);
/*Merge the two parts*/
inv_count += merge(arr, temp, left, mid+ 1 , right);
}
return inv_count;
}
// This function sorts the input array and
// returns the number of inversions in the
// array
static int countPairs( int arr[], int n)
{
// Modify the array so that problem reduces to
// count inversion problem.
for ( int i = 0 ; i < n; i++)
arr[i] = i * arr[i];
// Count inversions using same logic as
// below post
int temp[] = new int [n];
return _mergeSort(arr, temp, 0 , n - 1 );
}
// Driver code
public static void main (String[] args)
{
int arr[] = { 5 , 0 , 10 , 2 , 4 , 1 , 6 };
int n = arr.length;
System.out.print( "Count of Pairs : "
+ countPairs(arr, n));
}
} // This code is contributed by vt_m |
# Python 3 program to count all # pair that hold condition # i*arr[i] > j*arr[j] # This function merges two # sorted arrays and returns # inversion count in the arrays. def merge(arr, temp, left, mid, right):
inv_count = 0
i = left # index for left subarray
j = mid # index for right subarray
k = left # index for resultant subarray
while ((i < = mid - 1 ) and (j < = right)):
if (arr[i] < = arr[j]):
temp[k] = arr[i]
i + = 1
k + = 1
else :
temp[k] = arr[j]
k + = 1
j + = 1
inv_count = inv_count + (mid - i)
# Copy the remaining elements of left
# subarray (if there are any) to temp
while (i < = mid - 1 ):
temp[k] = arr[i]
i + = 1
k + = 1
# Copy the remaining elements of right
# subarray (if there are any) to temp
while (j < = right):
temp[k] = arr[j]
k + = 1
j + = 1
# Copy back the merged elements
# to original array
for i in range (left, right + 1 ):
arr[i] = temp[i]
return inv_count
# An auxiliary recursive function # that sorts the input array and # returns the number of inversions # in the array. def _mergeSort(arr, temp, left, right):
inv_count = 0
if (right > left):
# Divide the array into two parts
# and call _mergeSortAndCountInv()
# for each of the parts
mid = (right + left) / / 2
# Inversion count will be sum of
# inversions in left-part, right-part x
# and number of inversions in merging
inv_count = _mergeSort(arr, temp, left, mid)
inv_count + = _mergeSort(arr, temp,
mid + 1 , right)
# Merge the two parts
inv_count + = merge(arr, temp, left,
mid + 1 , right)
return inv_count
# This function sorts the input # array and returns the number # of inversions in the array def countPairs(arr, n):
# Modify the array so that problem
# reduces to count inversion problem.
for i in range (n):
arr[i] = i * arr[i]
# Count inversions using same
# logic as below post
temp = [ 0 ] * n
return _mergeSort(arr, temp, 0 , n - 1 )
# Driver code if __name__ = = "__main__" :
arr = [ 5 , 0 , 10 , 2 , 4 , 1 , 6 ]
n = len (arr)
print ( "Count of Pairs : " ,
countPairs(arr, n))
# This code is contributed # by ChitraNayal |
// C# program to count all pair that // hold condition i*arr[i] > j*arr[j] using System;
class GFG
{ // This function merges two sorted arrays and
// returns inversion count in the arrays.
static int merge( int []arr, int []temp, int left,
int mid, int right)
{
int inv_count = 0;
/* index for left subarray*/
int i = left;
/* index for right subarray*/
int j = mid;
/* index for resultant subarray*/
int k = left;
while ((i <= mid - 1) && (j <= right))
{
if (arr[i] <= arr[j])
temp[k++] = arr[i++];
else
{
temp[k++] = arr[j++];
inv_count = inv_count + (mid - i);
}
}
/* Copy the remaining elements of left
subarray (if there are any) to temp*/
while (i <= mid - 1)
temp[k++] = arr[i++];
/* Copy the remaining elements of right
subarray (if there are any) to temp*/
while (j <= right)
temp[k++] = arr[j++];
// Copy back the merged elements
// to original array
for (i = left; i <= right; i++)
arr[i] = temp[i];
return inv_count;
}
/* An auxiliary recursive function
that sorts the input array and
returns the number of inversions
in the array. */
static int _mergeSort( int []arr, int []temp,
int left, int right)
{
int mid, inv_count = 0;
if (right > left)
{
/* Divide the array into two parts and call
_mergeSortAndCountInv() for each of
the parts */
mid = (right + left) / 2;
// Inversion count will be sum of inversions in
// left-part, right-part and number of inversions
// in merging
inv_count = _mergeSort(arr, temp, left, mid);
inv_count += _mergeSort(arr, temp, mid+1, right);
/*Merge the two parts*/
inv_count += merge(arr, temp, left, mid+1, right);
}
return inv_count;
}
// This function sorts the input array and
// returns the number of inversions in the
// array
static int countPairs( int []arr, int n)
{
// Modify the array so that problem reduces to
// count inversion problem.
for ( int i = 0; i < n; i++)
arr[i] = i * arr[i];
// Count inversions using same logic as
// below post
int []temp = new int [n];
return _mergeSort(arr, temp, 0, n - 1);
}
// Driver code
public static void Main ()
{
int []arr = {5, 0, 10, 2, 4, 1, 6};
int n = arr.Length;
Console.WriteLine( "Count of Pairs : "
+ countPairs(arr, n));
}
} // This code is contributed by anuj_67. |
<script> // Javascript program to count all pair that // hold condition i*arr[i] > j*arr[j] // This function merges two sorted arrays and
// returns inversion count in the arrays.
function merge(arr,temp,left,mid,right)
{
let inv_count = 0;
/* index for left subarray*/
let i = left;
/* index for right subarray*/
let j = mid;
/* index for resultant subarray*/
let k = left;
while ((i <= mid - 1) && (j <= right))
{
if (arr[i] <= arr[j])
temp[k++] = arr[i++];
else
{
temp[k++] = arr[j++];
inv_count = inv_count + (mid - i);
}
}
/* Copy the remaining elements of left
subarray (if there are any) to temp*/
while (i <= mid - 1)
temp[k++] = arr[i++];
/* Copy the remaining elements of right
subarray (if there are any) to temp*/
while (j <= right)
temp[k++] = arr[j++];
// Copy back the merged elements
// to original array
for (i = left; i <= right; i++)
arr[i] = temp[i];
return inv_count;
}
/* An auxiliary recursive function
that sorts the input array and
returns the number of inversions
in the array. */
function _mergeSort(arr,temp,left,right)
{
let mid, inv_count = 0;
if (right > left)
{
/* Divide the array into two parts and call
_mergeSortAndCountInv() for each of
the parts */
mid = Math.floor((right + left) / 2);
// Inversion count will be sum of inversions in
// left-part, right-part and number of inversions
// in merging
inv_count = _mergeSort(arr, temp, left, mid);
inv_count += _mergeSort(arr, temp, mid+1, right);
/*Merge the two parts*/
inv_count += merge(arr, temp, left, mid+1, right);
}
return inv_count;
}
// This function sorts the input array and
// returns the number of inversions in the
// array
function countPairs(arr,n)
{
// Modify the array so that problem reduces to
// count inversion problem.
for (let i = 0; i < n; i++)
arr[i] = i * arr[i];
// Count inversions using same logic as
// below post
let temp = new Array(n);
for (let i=0;i<temp;i++)
{
temp[i]=0;
}
return _mergeSort(arr, temp, 0, n - 1);
}
// Driver code
let arr=[5, 0, 10, 2, 4, 1, 6];
let n = arr.length;
document.write( "Count of Pairs : "
+ countPairs(arr, n));
// This code is contributed by rag2127
</script> |
Count of Pairs : 5
Time Complexity: O(n log n)
Auxiliary Space: O(n)
Another efficient approach (Using policy-based data structures in C++ STL):
In this approach, we first store the value i*arr[i] for every index i and let name this array obtained as a modified array. So now instead of i*arr[i]>j*arr[j] in the original array, we have to find x>y where x and y are now elements of the modified array where the index of x is smaller than the index of y. In other words for every index i in the modified array, the total number of such pairs is the count of all the smaller elements to the right side of that index.
Hence the problem is transformed into another problem where we need to find the count of the smaller elements to the right side for each index i in the modified array.
So we can solve this problem efficiently by maintaining a policy-based data structure of pairs.
The steps involved are:
- Traverse through the array and for each index i store i*arr[i].
- Then traverse through the modified array from the end and every time we find the order_of_key of the current element to find the number of smaller elements to the right of it.
- Then we will add the obtained value from order_of_key of the current element into the ans variable.
- After that, we will insert the current element into our policy-based data structure.
Below is the code for the above approach:
// C++ implementation of the above approach #include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> #define pbds \ tree<pair< int , int >, null_type, less<pair< int , int > >, \
rb_tree_tag, tree_order_statistics_node_update>
using namespace __gnu_pbds;
using namespace std;
// Print the count of pair in given array // such that i*arr[i] > j*arr[j] // for 0<=i<j<n void countPrint( int arr[], int n)
{ // storing i*arr[i]
// for every index
for ( int i=0;i<n;i++)
{
arr[i]=i*arr[i];
}
pbds s;
// variable to store the count
int ans=0;
for ( int i = n - 1; i >= 0; i--) {
// for the last element count is
// zero so excluding it.
if (i!=n-1) {
// add the count of the smaller elements
// to the right of current element into
// the ans variable
ans+=s.order_of_key({ arr[i], i });
}
// insert current element
s.insert({ arr[i], i });
}
cout << ans << endl;
} // Driver Code int main()
{ int n = 7;
int arr[] = { 5 , 0, 10, 2, 4, 1, 6 };
countPrint(arr, n);
return 0;
} // This code is contributed by Pushpesh raj |
import java.util.*;
import java.util.AbstractMap.SimpleEntry;
public class Main {
// Print the count of pair in given array
// such that i*arr[i] > j*arr[j]
// for 0 <= i < j < n
static void countPrint( int [] arr, int n)
{
// storing i*arr[i]
// for every index
for ( int i = 0 ; i < n; i++) {
arr[i] = i * arr[i];
}
TreeMap<Integer, Integer> s = new TreeMap<>();
// variable to store the count
int ans = 0 ;
for ( int i = n - 1 ; i >= 0 ; i--)
{
// for the last element count is
// zero so excluding it.
if (i != n - 1 )
{
// add the count of the smaller elements
// to the right of current element into
// the ans variable
ans += s.headMap(arr[i]).size();
}
// insert current element
s.put(arr[i], i);
}
System.out.println(ans);
}
// Driver Code
public static void main(String[] args) {
int n = 7 ;
int [] arr = { 5 , 0 , 10 , 2 , 4 , 1 , 6 };
countPrint(arr, n);
}
} |
from bisect import bisect_left
# Print the count of pairs in given array # such that i*arr[i] > j*arr[j] # for 0 <= i < j < n def countPrint(arr, n):
# storing i*arr[i] for every index
for i in range (n):
arr[i] = i * arr[i]
s = []
ans = 0
for i in range (n - 1 , - 1 , - 1 ):
# for the last element, the count is zero, so excluding it
if i ! = n - 1 :
# add the count of smaller elements to the right of
# the current element into the ans variable
ans + = bisect_left(s, arr[i])
# insert current element
s.insert(bisect_left(s, arr[i]), arr[i])
print (ans)
# Driver Code if __name__ = = '__main__' :
n = 7
arr = [ 5 , 0 , 10 , 2 , 4 , 1 , 6 ]
countPrint(arr, n)
# This code is contributed by Aditya Sharma |
using System;
using System.Collections.Generic;
class MainClass {
// Print the count of pairs in given array
// such that i*arr[i] > j*arr[j]
// for 0 <= i < j < n
static void countPrint( int [] arr, int n)
{
// storing i*arr[i] for every index
for ( int i = 0; i < n; i++) {
arr[i] = i * arr[i];
}
List< int > s = new List< int >();
int ans = 0;
for ( int i = n - 1; i >= 0; i--) {
// for the last element, the count is zero, so
// excluding it
if (i != n - 1) {
// add the count of smaller elements to the
// right of the current element into the ans
// variable
ans += s.BinarySearch(arr[i]) >= 0
? s.BinarySearch(arr[i])
: ~s.BinarySearch(arr[i]);
}
// insert current element
s.Insert(s.BinarySearch(arr[i]) >= 0
? s.BinarySearch(arr[i])
: ~s.BinarySearch(arr[i]),
arr[i]);
}
Console.WriteLine(ans);
}
// Driver Code
public static void Main( string [] args)
{
int n = 7;
int [] arr = { 5, 0, 10, 2, 4, 1, 6 };
countPrint(arr, n);
}
} |
function countPrint(arr, n) {
// storing i*arr[i]
// for every index
for (let i = 0; i < n; i++) {
arr[i] = i * arr[i];
}
// using a map to store values of arr[i]
// and their corresponding counts
const s = new Map();
// variable to store the count
let ans = 0;
// iterating over the array in reverse order
for (let i = n - 1; i >= 0; i--) {
// for the last element count is
// zero so excluding it.
if (i != n - 1) {
// add the count of the smaller elements
// to the right of current element into
// the ans variable
for (const [key, value] of s.entries()) {
if (key < arr[i]) {
ans += value;
}
}
}
// insert current element
if (s.has(arr[i])) {
s.set(arr[i], s.get(arr[i]) + 1);
} else {
s.set(arr[i], 1);
}
}
console.log(ans);
} // Driver Code const n = 7; const arr = [5, 0, 10, 2, 4, 1, 6]; countPrint(arr, n); |
5
Time Complexity: O(n*log(n))
Auxiliary Space: O(n)