Counting inversions in an array using segment tree

Given an array of integers arr, the task is to count the number of inversions in the array.
If A[i] > A[j] and i then the pair (A[i], A[j]) is part of an inversion.

Examples:

Input: arr[] = {8, 4, 2, 1}
Output: 6

Input: arr[] = {3, 1, 2}
Output: 2



Approach:

Below is the implementation of the above approach:

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to count the inversions
// present in the array using segment tree
#include "algorithm"
#include "cstring"
#include "iostream"
using namespace std;
  
// Function to update segment tree
// i.e. to insert the element
void update(int* Tree, int index, int s, int e, int num)
{
    // Leaf node condition
    if (s == num and e == num) {
        Tree[index] = 1;
        return;
    }
  
    // No overlap condition
    if (num < s or num > e) {
        return;
    }
  
    // Else call on both the children nodes
    int mid = (s + e) >> 1;
    update(Tree, 2 * index, s, mid, num);
    update(Tree, 2 * index + 1, mid + 1, e, num);
  
    Tree[index] = Tree[2 * index] + Tree[2 * index + 1];
}
  
// Function to count the total numbers
// present in the range [a[i]+1, mx]
int query(int* Tree, int index, int s,
          int e, int qs, int qe)
{
    // Complete overlap
    if (qs <= s and e <= qe) {
        return Tree[index];
    }
  
    // No Overlap
    if (s > qe or e < qs) {
        return 0;
    }
  
    int mid = (s + e) >> 1;
  
    return query(Tree, 2 * index, s,
                 mid, qs, qe)
           + query(Tree, 2 * index + 1,
                   mid + 1, e, qs, qe);
}
  
// Driver code
int main(int argc, char const* argv[])
{
    int arr[] = { 8, 4, 2, 1 };
    int n = sizeof(arr) / sizeof(arr[0]);
  
    // Maximum element present in the array.
    int mx = *max_element(arr, arr + n);
  
    // Segment Tree
    int Tree[6 * mx];
  
    // Initialize every node
    // of segment tree to 0
    memset(Tree, 0, sizeof(Tree));
  
    int answer = 0;
  
    for (int i = 0; i < n; ++i) {
  
        // add the count of inversion pair
        // formed with the element a[i] and the
        // elements appearing before the index i.
        answer += query(Tree, 1, 1, mx, arr[i] + 1, mx);
  
        // Insert the a[i] in the segment tree
        update(Tree, 1, 1, mx, arr[i]);
    }
  
    cout << answer;
    return 0;
}
chevron_right

Output:
6



Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.




Article Tags :
Practice Tags :