Counting inversions in an array using segment tree - GeeksforGeeks

31 May, 2021
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 < j then the pair (A[i], A[j]) is part of an inversion.Examples:  
Input: arr[] = {8, 4, 2, 1} Output: 6Input: arr[] = {3, 1, 2} Output: 2  
 
Approach:  
Build a segment tree where each node will represent the total numbers present in the range of that node.
Let’s say the range of any node is [i, j], then the node will contain the count of numbers which are greater than or equal to i and less than or equal to j.
Leaf nodes will only be either 1 or 0 since range of the node will be 1.
Iterate through the array, let the number present at the index i is a[i]. We will find how many numbers are present in the segment tree in the range [a[i]+1, max] where max is the maximum element of the array and add it to the answer variable.
Then we will insert that number in the segment tree and continue till the last index of the array. This way for each element we are adding the numbers which appear before that element and are greater than that element i.e. they form an inversion pair.
Below is the implementation of the above approach:  
C++
Java
Python3
C#
Javascript
// 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 elementvoid 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 codeint 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;}
// Java program to count the inversions// present in the array using segment treeimport java.io.*;import java.util.Arrays;class GFG{   // Function to update segment tree  // i.e. to insert the element  static void update(int[] Tree, int index,                     int s, int e, int num)  {     // Leaf node condition    if (s == num && e == num)    {      Tree[index] = 1;      return;    }     // No overlap condition    if (num < s || 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]  static int query(int[] Tree, int index, int s,                   int e, int qs, int qe)  {    // Complete overlap    if (qs <= s && e <= qe)    {      return Tree[index];    }     // No Overlap    if (s > qe || 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  public static void main (String[] args)  {    int arr[] = { 8, 4, 2, 1 };    int n = arr.length;     // Maximum element present in the array.    int mx = Arrays.stream(arr).max().getAsInt();     // Segment Tree    int[] Tree = new int[6 * mx];    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]);    }       System.out.println(answer);  }} // This code is contributed by rag2127
# Python3 program to count the inversions# present in the array using segment tree # Function to update segment tree# i.e. to insert the elementdef update(Tree, index, s, e, 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    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]def query(Tree,index, s,e, qs, qe):         # Complete overlap    if (qs <= s and e <= qe):        return Tree[index]     # No Overlap    if (s > qe or e < qs):        return 0     mid = (s + e) >> 1     return query(Tree, 2 * index, s,mid, qs, qe) +\           query(Tree, 2 * index + 1, mid + 1, e, qs, qe) # Driver codeif __name__ == '__main__':    arr = [8, 4, 2, 1]    n = len(arr)     # Maximum element present in the array.    mx = max(arr)     # Segment Tree    Tree = [0] * (6 * mx)     # Initialize every node    # of segment tree to 0    answer = 0     for i in range(n):         # 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])     print(answer) # This code is contributed by Mohit Kumar
using System;using System.Linq; class GFG{   // Function to update segment tree  // i.e. to insert the element  static void update(int[] Tree, int index,                     int s, int e, int num)  {     // Leaf node condition    if (s == num && e == num)    {      Tree[index] = 1;      return;    }     // No overlap condition    if (num < s || 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]  static int query(int[] Tree, int index,                   int s, int e, int qs, int qe)  {     // Complete overlap    if (qs <= s && e <= qe)    {      return Tree[index];    }     // No Overlap    if (s > qe || 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  static public void Main ()  {    int[] arr = { 8, 4, 2, 1 };    int n = arr.Length;     // Maximum element present in the array.    int mx =  arr.Max();     // Segment Tree    int[] Tree = new int[6 * mx];    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]);    }      Console.WriteLine(answer);  }} // This code is contributed by avanitrachhadiya2155
<script> // JavaScript program to count the inversions// present in the array using segment tree  // Function to update segment tree  // i.e. to insert the elementfunction update(Tree,index,s,e,num){    // Leaf node condition    if (s == num && e == num)    {      Tree[index] = 1;      return;    }      // No overlap condition    if (num < s || num > e)    {      return;    }      // Else call on both the children nodes    let 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]  function query(Tree, index, s,                    e,  qs,  qe)  {    // Complete overlap    if (qs <= s && e <= qe)    {      return Tree[index];    }      // No Overlap    if (s > qe || e < qs)    {      return 0;    }    let 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 let arr=[ 8, 4, 2, 1 ];let n = arr.length; // Maximum element present in the array.    let mx = Math.max(...arr);      // Segment Tree    let Tree = new Array(6 * mx);    for(let i=0;i<Tree.length;i++)    {        Tree[i]=0;    }    let answer = 0;    for (let 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]);    }      document.write(answer);      // This code is contributed by unknown2108 </script>
6
 
mohit kumar 29
rag2127
avanitrachhadiya2155
unknown2108
inversion
Picked
Segment-Tree
Technical Scripter 2018
Advanced Data Structure
Competitive Programming
Technical Scripter
Tree
Tree
Segment-Tree
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
Agents in Artificial Intelligence
Red-Black Tree | Set 2 (Insert)
Decision Tree Introduction with example
Disjoint Set Data Structures
AVL Tree | Set 2 (Deletion)
Arrow operator -> in C/C++ with Examples
Practice for cracking any coding interview
Competitive Programming - A Complete Guide
Bits manipulation (Important tactics)
String hashing using Polynomial rolling hash function