Counting Inversions using Ordered Set and GNU C++ PBDS
Given an array arr[] of N integers. The task is to find the number of inversion. Two elements arr[i] and arr[j] form an inversion if arr[i] > arr[j] and i < j.
Examples
Input: arr[] = {8, 4, 2, 1}
Output: 6
Explanation:
Given array has six inversions:
- (8, 4): arr[0] > arr[1] and 0 < 1
- (8, 2): arr[0] > arr[2] and 0 < 2
- (8, 1): arr[0] > arr[3] and 0 < 3
- (4, 2): arr[1] > arr[2] and 1 < 2
- (4, 1): arr[1] > arr[3] and 1 < 3
- (2, 1): arr[2] > arr[3] and 2 < 3
Input: arr[] = {2, 3}
Output: 0
Explanation:
There is no such pair exists such that arr[i] > arr[j] and i < j.
We have already discussed below approaches:
In this post, we will be discussing an approach using Ordered Set and GNU C++ PBDS.
Approach:
We will be using the function order_of_key(K) which returns number of elements strictly smaller than K in log N time.
- Insert the first element of the array in the Ordered_Set.
- For all the remaining element in arr[] do the following:
- Insert the current element in the Ordered_Set.
- Find the number of element strictly less than current element + 1 in Ordered_Set using function order_of_key(arr[i]+1).
- The difference between size of Ordered_Set and order_of_key(current_element + 1) will give the inversion count for the current element.
For Example:
arr[] = {8, 4, 2, 1}
Ordered_Set S = {8}
For remaining element in arr[]:
At index 1, the element is 4
S = {4, 8}
key = order_of_key(5) = 1
The difference between size of S and key gives the total
number of inversion count for that current element.
inversion_count = S.size() - key = 2 - 1 = 1
Inversion Pairs are: (8, 4)
At index 2, the element is 2
S = {2, 4, 8}
key = order_of_key(3) = 1
inversion_count = S.size() - key = 3 - 1 = 2
Inversion Pairs are: (8, 2) and (4, 2)
At index 3, the element is 1
S = {1, 2, 4, 8}
key = order_of_key(2) = 1
inversion_count = S.size() - key = 4 - 1 = 3
Inversion Pairs are: (8, 1), (4, 1) and (2, 1)
Total inversion count = 1 + 2 + 3 = 6
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;
typedef tree< int , null_type, less_equal< int >,
rb_tree_tag,
tree_order_statistics_node_update>
ordered_set;
int getInvCount( int arr[], int n)
{
int key;
ordered_set set1;
set1.insert(arr[0]);
int invcount = 0;
for ( int i = 1; i < n; i++) {
set1.insert(arr[i]);
key = set1.order_of_key(arr[i] + 1);
invcount += set1.size() - key;
}
return invcount;
}
int main()
{
int arr[] = { 8, 4, 2, 1 };
int n = sizeof (arr) / sizeof ( int );
cout << getInvCount(arr, n);
return 0;
}
|
Time Complexity: O(Nlog N)
Last Updated :
22 Mar, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...