Contar inversiones en una array | Conjunto 3 (usando BIT)

El conteo de inversión para una array indica qué tan lejos (o cerca) está la array de ser ordenada. Si la array ya está ordenada, el recuento de inversión es 0. Si la array está ordenada en orden inverso, el recuento de inversión es el máximo. 
Dos elementos a[i] y a[j] forman una inversión si a[i] > a[j] e i < j. Para simplificar, podemos suponer que todos los elementos son únicos.
Ejemplo: 

Entrada: arr[] = {8, 4, 2, 1}
Salida: 6
Explicación: La array dada tiene seis inversiones: (8,4), (4,2), (8,2), (8,1), (4,1), (2,1).     

Entrada: arr[] = {3, 1, 2}
Salida: 2
Explicación: La array dada tiene dos inversiones: (3,1), (3,2).

Le recomendamos encarecidamente que haga clic aquí y lo practique antes de pasar a la solución.

Ya hemos discutido los siguientes métodos para resolver el conteo de inversión:  

  1. Clasificación de combinación ingenua y modificada
  2. Uso del árbol AVL

Le recomendamos que consulte el Árbol indexado binario (BIT) antes de seguir leyendo esta publicación. 
Solución usando BIT de tamaño Θ(maxElement):  

  • Enfoque: recorra la array y, para cada índice, encuentre la cantidad de elementos más pequeños en el lado derecho de la array. Esto se puede hacer usando BIT. Sume los recuentos de todos los índices de la array e imprima la suma.
  • Antecedentes sobre el TBI: 
    1. BIT básicamente admite dos operaciones para una array arr[] de tamaño n: 
      1. Suma de elementos hasta arr[i] en tiempo O(log n).
      2. Actualice un elemento de array en tiempo O (log n).
    2. BIT se implementa mediante una array y funciona en forma de árboles. Tenga en cuenta que hay dos formas de ver BIT como un árbol. 
      1. La operación de suma donde el padre del índice x es “x – (x & -x)”.
      2. La operación de actualización donde el padre del índice x es «x + (x & -x)».
  • Algoritmo: 
    1. Cree un BIT, para encontrar el conteo de los elementos más pequeños en el BIT para un número dado y también un resultado variable = 0 .
    2. Atraviesa la array de un extremo a otro.
    3. Para cada índice, verifique cuántos números menos que el elemento actual están presentes en BIT y agréguelos al resultado
    4. Para obtener el recuento de elementos más pequeños, se utiliza getSum() de BIT .
    5. En su idea básica, BIT se representa como una array de tamaño igual al elemento máximo más uno. Para que los elementos se puedan usar como un índice.
    6. Después de eso, agregamos el elemento actual al BIT[] realizando una operación de actualización que actualiza el conteo del elemento actual de 0 a 1 y, por lo tanto, actualiza los ancestros del elemento actual en BIT (consulte update() en BIT para obtener más detalles) .

A continuación se muestra la implementación del enfoque anterior:

C++

// C++ program to count inversions using Binary Indexed Tree
#include<bits/stdc++.h>
using namespace std;
 
// Returns sum of arr[0..index]. This function assumes
// that the array is preprocessed and partial sums of
// array elements are stored in BITree[].
int getSum(int BITree[], int index)
{
    int sum = 0; // Initialize result
 
    // Traverse ancestors of BITree[index]
    while (index > 0)
    {
        // Add current element of BITree to sum
        sum += BITree[index];
 
        // Move index to parent node in getSum View
        index -= index & (-index);
    }
    return sum;
}
 
// Updates a node in Binary Index Tree (BITree) at given index
// in BITree.  The given value 'val' is added to BITree[i] and
// all of its ancestors in tree.
void updateBIT(int BITree[], int n, int index, int val)
{
    // Traverse all ancestors and add 'val'
    while (index <= n)
    {
       // Add 'val' to current node of BI Tree
       BITree[index] += val;
 
       // Update index to that of parent in update View
       index += index & (-index);
    }
}
 
// Returns inversion count arr[0..n-1]
int getInvCount(int arr[], int n)
{
    int invcount = 0; // Initialize result
 
    // Find maximum element in arr[]
    int maxElement = 0;
    for (int i=0; i<n; i++)
        if (maxElement < arr[i])
            maxElement = arr[i];
 
    // Create a BIT with size equal to maxElement+1 (Extra
    // one is used so that elements can be directly be
    // used as index)
    int BIT[maxElement+1];
    for (int i=1; i<=maxElement; i++)
        BIT[i] = 0;
 
    // Traverse all elements from right.
    for (int i=n-1; i>=0; i--)
    {
        // Get count of elements smaller than arr[i]
        invcount += getSum(BIT, arr[i]-1);
 
        // Add current element to BIT
        updateBIT(BIT, maxElement, arr[i], 1);
    }
 
    return invcount;
}
 
// Driver program
int main()
{
    int arr[] = {8, 4, 2, 1};
    int n = sizeof(arr)/sizeof(int);
    cout << "Number of inversions are : " << getInvCount(arr,n);
    return 0;
}

Java

// Java program to count inversions
// using Binary Indexed Tree
 
class GFG
{
     
// Returns sum of arr[0..index].
// This function assumes that the
// array is preprocessed and partial
// sums of array elements are stored
// in BITree[].
static int getSum(int[] BITree, int index)
{
    int sum = 0; // Initialize result
 
    // Traverse ancestors of BITree[index]
    while (index > 0)
    {
        // Add current element of BITree to sum
        sum += BITree[index];
 
        // Move index to parent node in getSum View
        index -= index & (-index);
    }
    return sum;
}
 
// Updates a node in Binary Index
// Tree (BITree) at given index
// in BITree. The given value 'val'
// is added to BITree[i] and all
// of its ancestors in tree.
static void updateBIT(int[] BITree, int n,
                        int index, int val)
{
    // Traverse all ancestors and add 'val'
    while (index <= n)
    {
        // Add 'val' to current node of BI Tree
        BITree[index] += val;
 
        // Update index to that of parent in update View
        index += index & (-index);
    }
}
 
// Returns inversion count arr[0..n-1]
static int getInvCount(int[] arr, int n)
{
    int invcount = 0; // Initialize result
 
    // Find maximum element in arr[]
    int maxElement = 0;
    for (int i = 0; i < n; i++)
        if (maxElement < arr[i])
            maxElement = arr[i];
 
    // Create a BIT with size equal to
    // maxElement+1 (Extra one is used so
    // that elements can be directly be
    // used as index)
    int[] BIT = new int[maxElement + 1];
    for (int i = 1; i <= maxElement; i++)
        BIT[i] = 0;
 
    // Traverse all elements from right.
    for (int i = n - 1; i >= 0; i--)
    {
        // Get count of elements smaller than arr[i]
        invcount += getSum(BIT, arr[i] - 1);
 
        // Add current element to BIT
        updateBIT(BIT, maxElement, arr[i], 1);
    }
 
    return invcount;
}
 
// Driver code
public static void main (String[] args)
{
    int []arr = {8, 4, 2, 1};
    int n = arr.length;
    System.out.println("Number of inversions are : " +
                                getInvCount(arr,n));
}
}
 
// This code is contributed by mits

Python3

# Python3 program to count inversions using
# Binary Indexed Tree
 
# Returns sum of arr[0..index]. This function
# assumes that the array is preprocessed and
# partial sums of array elements are stored
# in BITree[].
def getSum( BITree, index):
    sum = 0 # Initialize result
     
    # Traverse ancestors of BITree[index]
    while (index > 0):
 
        # Add current element of BITree to sum
        sum += BITree[index]
 
        # Move index to parent node in getSum View
        index -= index & (-index)
 
    return sum
 
# Updates a node in Binary Index Tree (BITree)
# at given index in BITree. The given value
# 'val' is added to BITree[i] and all of its
# ancestors in tree.
def updateBIT(BITree, n, index, val):
 
    # Traverse all ancestors and add 'val'
    while (index <= n):
 
        # Add 'val' to current node of BI Tree
        BITree[index] += val
 
        # Update index to that of parent
        # in update View
        index += index & (-index)
 
# Returns count of inversions of size three
def getInvCount(arr, n):
 
    invcount = 0 # Initialize result
 
    # Find maximum element in arrays
    maxElement = max(arr)
 
    # Create a BIT with size equal to
    # maxElement+1 (Extra one is used
    # so that elements can be directly
    # be used as index)
    BIT = [0] * (maxElement + 1)
    for i in range(n - 1, -1, -1):
 
        invcount += getSum(BIT, arr[i] - 1)
        updateBIT(BIT, maxElement, arr[i], 1)
    return invcount
     
# Driver code
if __name__ =="__main__":
    arr = [8, 4, 2, 1]
    n = 4
    print("Inversion Count : ",
           getInvCount(arr, n))
     
# This code is contributed by
# Shubham Singh(SHUBHAMSINGH10)

C#

// C# program to count inversions
// using Binary Indexed Tree
using System;
 
class GFG
{
     
// Returns sum of arr[0..index].
// This function assumes that the
// array is preprocessed and partial
// sums of array elements are stored
// in BITree[].
static int getSum(int []BITree, int index)
{
    int sum = 0; // Initialize result
 
    // Traverse ancestors of BITree[index]
    while (index > 0)
    {
        // Add current element of BITree to sum
        sum += BITree[index];
 
        // Move index to parent node in getSum View
        index -= index & (-index);
    }
    return sum;
}
 
// Updates a node in Binary Index
// Tree (BITree) at given index
// in BITree. The given value 'val'
// is added to BITree[i] and all
// of its ancestors in tree.
static void updateBIT(int []BITree, int n,
                        int index, int val)
{
    // Traverse all ancestors and add 'val'
    while (index <= n)
    {
        // Add 'val' to current node of BI Tree
        BITree[index] += val;
 
        // Update index to that of parent in update View
        index += index & (-index);
    }
}
 
// Returns inversion count arr[0..n-1]
static int getInvCount(int []arr, int n)
{
    int invcount = 0; // Initialize result
 
    // Find maximum element in arr[]
    int maxElement = 0;
    for (int i = 0; i < n; i++)
        if (maxElement < arr[i])
            maxElement = arr[i];
 
    // Create a BIT with size equal to
    // maxElement+1 (Extra one is used so
    // that elements can be directly be
    // used as index)
    int[] BIT = new int[maxElement + 1];
    for (int i = 1; i <= maxElement; i++)
        BIT[i] = 0;
 
    // Traverse all elements from right.
    for (int i = n - 1; i >= 0; i--)
    {
        // Get count of elements smaller than arr[i]
        invcount += getSum(BIT, arr[i] - 1);
 
        // Add current element to BIT
        updateBIT(BIT, maxElement, arr[i], 1);
    }
 
    return invcount;
}
 
// Driver code
static void Main()
{
    int []arr = {8, 4, 2, 1};
    int n = arr.Length;
    Console.WriteLine("Number of inversions are : " +
                                getInvCount(arr,n));
}
}
 
// This code is contributed by mits

PHP

<?php
// PHP program to count inversions
// using Binary Indexed Tree
 
// Returns sum of arr[0..index].
// This function assumes that the
// array is preprocessed and partial
// sums of array elements are stored
// in BITree[].
function getSum($BITree, $index)
{
    $sum = 0; // Initialize result
 
    // Traverse ancestors of BITree[index]
    while ($index > 0)
    {
        // Add current element of BITree to sum
        $sum += $BITree[$index];
 
        // Move index to parent node in getSum View
        $index -= $index & (-$index);
    }
    return $sum;
}
 
// Updates a node in Binary Index
// Tree (BITree) at given index
// in BITree. The given value 'val'
// is added to BITree[i] and
// all of its ancestors in tree.
function updateBIT(&$BITree, $n, $index,$val)
{
    // Traverse all ancestors and add 'val'
    while ($index <= $n)
    {
        // Add 'val' to current node of BI Tree
        $BITree[$index] += $val;
 
        // Update index to that of
        // parent in update View
        $index += $index & (-$index);
    }
}
 
// Returns inversion count arr[0..n-1]
function getInvCount($arr, $n)
{
    $invcount = 0; // Initialize result
 
    // Find maximum element in arr[]
    $maxElement = 0;
    for ($i=0; $i<$n; $i++)
        if ($maxElement < $arr[$i])
            $maxElement = $arr[$i];
 
    // Create a BIT with size equal
    // to maxElement+1 (Extra one is
    // used so that elements can be
    // directly be used as index)
    $BIT=array_fill(0,$maxElement+1,0);
 
    // Traverse all elements from right.
    for ($i=$n-1; $i>=0; $i--)
    {
        // Get count of elements smaller than arr[i]
        $invcount += getSum($BIT, $arr[$i]-1);
 
        // Add current element to BIT
        updateBIT($BIT, $maxElement, $arr[$i], 1);
    }
 
    return $invcount;
}
 
    // Driver program
    $arr = array(8, 4, 2, 1);
    $n = count($arr);
    print("Number of inversions are : ".getInvCount($arr,$n));
 
// This code is contributed by mits
?>

Javascript

<script>
// javascript program to count inversions
// using Binary Indexed Tree  
// Returns sum of arr[0..index].
// This function assumes that the
// array is preprocessed and partial
// sums of array elements are stored
// in BITree.
function getSum(BITree , index)
{
    var sum = 0; // Initialize result
 
    // Traverse ancestors of BITree[index]
    while (index > 0)
    {
        // Add current element of BITree to sum
        sum += BITree[index];
 
        // Move index to parent node in getSum View
        index -= index & (-index);
    }
    return sum;
}
 
// Updates a node in Binary Index
// Tree (BITree) at given index
// in BITree. The given value 'val'
// is added to BITree[i] and all
// of its ancestors in tree.
function updateBIT(BITree , n, index , val)
{
    // Traverse all ancestors and add 'val'
    while (index <= n)
    {
        // Add 'val' to current node of BI Tree
        BITree[index] += val;
 
        // Update index to that of parent in update View
        index += index & (-index);
    }
}
 
// Returns inversion count arr[0..n-1]
function getInvCount(arr , n)
{
    var invcount = 0; // Initialize result
 
    // Find maximum element in arr
    var maxElement = 0;
    for (i = 0; i < n; i++)
        if (maxElement < arr[i])
            maxElement = arr[i];
 
    // Create a BIT with size equal to
    // maxElement+1 (Extra one is used so
    // that elements can be directly be
    // used as index)
    var BIT = Array.from({length: maxElement + 1}, (_, i) => 0);
    for (i = 1; i <= maxElement; i++)
        BIT[i] = 0;
 
    // Traverse all elements from right.
    for (i = n - 1; i >= 0; i--)
    {
        // Get count of elements smaller than arr[i]
        invcount += getSum(BIT, arr[i] - 1);
 
        // Add current element to BIT
        updateBIT(BIT, maxElement, arr[i], 1);
    }
 
    return invcount;
}
 
// Driver code
    var arr = [8, 4, 2, 1];
    var n = arr.length;
    document.write("Number of inversions are : " +
                                getInvCount(arr,n));
 
// This code is contributed by Amit Katiyar
</script>
Producción

Number of inversions are : 6

Complejidad de tiempo: – La función de actualización y la función getSum se ejecutan para O (log (elemento máximo)). La función getSum debe ejecutarse para cada elemento de la array. Entonces, la complejidad del tiempo general es: O (nlog (elemento máximo)).
Espacio auxiliar: O(maxElement), el espacio requerido para el BIT es una array del tamaño del elemento más grande.

Mejor solución usando BIT de tamaño Θ(n): 
Enfoque: Atraviese la array y para cada índice encuentre la cantidad de elementos más pequeños en su lado derecho de la array. Esto se puede hacer usando BIT. Sume los recuentos de todos los índices de la array e imprima la suma. El enfoque sigue siendo el mismo, pero el problema con el enfoque anterior es que no funciona para números negativos, ya que el índice no puede ser negativo. La idea es convertir la array dada en una array con valores de 1 a n y el orden relativo de los elementos más pequeños y más grandes sigue siendo el mismo.
Ejemplo :

 
arr[] = {7, -90, 100, 1}
It gets  converted to,
arr[] = {3, 1, 4 ,2 }
as -90 < 1 < 7 < 100.

Explanation: Make a BIT array of a number of
elements instead of a maximum element. Changing
element will not have any change in the answer
as the greater elements remain greater and at the
same position. 

Algoritmo: 

  1. Cree un BIT, para encontrar el conteo de los elementos más pequeños en el BIT para un número dado y también un resultado variable = 0 .
  2. La solución anterior no funciona para arrays que contienen elementos negativos. Entonces, convierta la array en una array que contenga una numeración relativa de elementos, es decir, haga una copia de la array original y luego ordene la copia de la array y reemplace los elementos de la array original con los índices de los mismos elementos en la array ordenada. 
    Por ejemplo, si la array es {-3, 2, 0}, la array se convierte en {1, 3, 2}
  3. Atraviesa la array de un extremo a otro.
  4. Para cada índice, verifique cuántos números menos que el elemento actual están presentes en BIT y agréguelos al resultado

A continuación se muestra la implementación del enfoque anterior: 

C++

// C++ program to count inversions using Binary Indexed Tree
#include<bits/stdc++.h>
using namespace std;
 
// Returns sum of arr[0..index]. This function assumes
// that the array is preprocessed and partial sums of
// array elements are stored in BITree[].
int getSum(int BITree[], int index)
{
    int sum = 0; // Initialize result
 
    // Traverse ancestors of BITree[index]
    while (index > 0)
    {
        // Add current element of BITree to sum
        sum += BITree[index];
 
        // Move index to parent node in getSum View
        index -= index & (-index);
    }
    return sum;
}
 
// Updates a node in Binary Index Tree (BITree) at given index
// in BITree.  The given value 'val' is added to BITree[i] and
// all of its ancestors in tree.
void updateBIT(int BITree[], int n, int index, int val)
{
    // Traverse all ancestors and add 'val'
    while (index <= n)
    {
       // Add 'val' to current node of BI Tree
       BITree[index] += val;
 
       // Update index to that of parent in update View
       index += index & (-index);
    }
}
 
// Converts an array to an array with values from 1 to n
// and relative order of smaller and greater elements remains
// same.  For example, {7, -90, 100, 1} is converted to
// {3, 1, 4 ,2 }
void convert(int arr[], int n)
{
    // Create a copy of arrp[] in temp and sort the temp array
    // in increasing order
    int temp[n];
    for (int i=0; i<n; i++)
        temp[i] = arr[i];
    sort(temp, temp+n);
 
    // Traverse all array elements
    for (int i=0; i<n; i++)
    {
        // lower_bound() Returns pointer to the first element
        // greater than or equal to arr[i]
        arr[i] = lower_bound(temp, temp+n, arr[i]) - temp + 1;
    }
}
 
// Returns inversion count arr[0..n-1]
int getInvCount(int arr[], int n)
{
    int invcount = 0; // Initialize result
 
     // Convert arr[] to an array with values from 1 to n and
     // relative order of smaller and greater elements remains
     // same.  For example, {7, -90, 100, 1} is converted to
    //  {3, 1, 4 ,2 }
    convert(arr, n);
 
    // Create a BIT with size equal to maxElement+1 (Extra
    // one is used so that elements can be directly be
    // used as index)
    int BIT[n+1];
    for (int i=1; i<=n; i++)
        BIT[i] = 0;
 
    // Traverse all elements from right.
    for (int i=n-1; i>=0; i--)
    {
        // Get count of elements smaller than arr[i]
        invcount += getSum(BIT, arr[i]-1);
 
        // Add current element to BIT
        updateBIT(BIT, n, arr[i], 1);
    }
 
    return invcount;
}
 
// Driver program
int main()
{
    int arr[] = {8, 4, 2, 1};
    int n = sizeof(arr)/sizeof(int);
    cout << "Number of inversions are : " << getInvCount(arr,n);
    return 0;
}

Java

// Java program to count inversions
// using Binary Indexed Tree
import java.util.*;
class GFG{
 
// Returns sum of arr[0..index].
// This function assumes that the
// array is preprocessed and partial
// sums of array elements are stored
// in BITree[].
static int getSum(int BITree[],
                  int index)
{
  // Initialize result
  int sum = 0;
 
  // Traverse ancestors of
  // BITree[index]
  while (index > 0)
  {
    // Add current element of
    // BITree to sum
    sum += BITree[index];
 
    // Move index to parent node
    // in getSum View
    index -= index & (-index);
  }
  return sum;
}
 
// Updates a node in Binary Index Tree
// (BITree) at given index in BITree. 
// The given value 'val' is added to
// BITree[i] and all of its ancestors
// in tree.
static void updateBIT(int BITree[], int n,
                      int index, int val)
{
  // Traverse all ancestors
  // and add 'val'
  while (index <= n)
  {
    // Add 'val' to current
    // node of BI Tree
    BITree[index] += val;
 
    // Update index to that of
    // parent in update View
    index += index & (-index);
  }
}
 
// Converts an array to an array
// with values from 1 to n and
// relative order of smaller and
// greater elements remains same. 
// For example, {7, -90, 100, 1}
// is converted to {3, 1, 4 ,2 }
static void convert(int arr[],
                    int n)
{
  // Create a copy of arrp[] in temp
  // and sort the temp array in
  // increasing order
  int []temp = new int[n];
   
  for (int i = 0; i < n; i++)
    temp[i] = arr[i];
  Arrays.sort(temp);
 
  // Traverse all array elements
  for (int i = 0; i < n; i++)
  {
    // lower_bound() Returns pointer
    // to the first element greater
    // than or equal to arr[i]
    arr[i] =lower_bound(temp,0,
                        n, arr[i]) + 1;
  }
}
 
static int lower_bound(int[] a, int low,
                       int high, int element)
{
  while(low < high)
  {
    int middle = low +
                (high - low) / 2;
    if(element > a[middle])
      low = middle + 1;
    else
      high = middle;
  }
  return low;
}
 
// Returns inversion count
// arr[0..n-1]
static int getInvCount(int arr[],
                       int n)
{
  // Initialize result
  int invcount = 0;
 
  // Convert arr[] to an array
  // with values from 1 to n and
  // relative order of smaller
  // and greater elements remains
  // same.  For example, {7, -90,
  // 100, 1} is converted to
  //  {3, 1, 4 ,2 }
  convert(arr, n);
 
  // Create a BIT with size equal
  // to maxElement+1 (Extra one is
  // used so that elements can be
  // directly be used as index)
  int []BIT = new int[n + 1];
   
  for (int i = 1; i <= n; i++)
    BIT[i] = 0;
 
  // Traverse all elements
  // from right.
  for (int i = n - 1; i >= 0; i--)
  {
    // Get count of elements
    // smaller than arr[i]
    invcount += getSum(BIT,
                       arr[i] - 1);
 
    // Add current element to BIT
    updateBIT(BIT, n, arr[i], 1);
  }
 
  return invcount;
}
 
// Driver code
public static void main(String[] args)
{
  int arr[] = {8, 4, 2, 1};
  int n = arr.length;
  System.out.print("Number of inversions are : " + 
                    getInvCount(arr, n));
}
}
 
// This code is contributed by Amit Katiyar

Python3

# Python3 program to count inversions using Binary Indexed Tree
from bisect import bisect_left as lower_bound
 
# Returns sum of arr[0..index]. This function assumes
# that the array is preprocessed and partial sums of
# array elements are stored in BITree.
def getSum(BITree, index):
 
    sum = 0 # Initialize result
 
    # Traverse ancestors of BITree[index]
    while (index > 0):
 
        # Add current element of BITree to sum
        sum += BITree[index]
 
        # Move index to parent node in getSum View
        index -= index & (-index)
 
    return sum
 
# Updates a node in Binary Index Tree (BITree) at given index
# in BITree. The given value 'val' is added to BITree[i] and
# all of its ancestors in tree.
def updateBIT(BITree, n, index, val):
 
    # Traverse all ancestors and add 'val'
    while (index <= n):
 
        # Add 'val' to current node of BI Tree
        BITree[index] += val
 
    # Update index to that of parent in update View
    index += index & (-index)
 
# Converts an array to an array with values from 1 to n
# and relative order of smaller and greater elements remains
# same. For example, 7, -90, 100, 1 is converted to
# 3, 1, 4 ,2
def convert(arr, n):
 
    # Create a copy of arrp in temp and sort the temp array
    # in increasing order
    temp = [0]*(n)
    for i in range(n):
        temp[i] = arr[i]
    temp = sorted(temp)
 
    # Traverse all array elements
    for i in range(n):
 
        # lower_bound() Returns pointer to the first element
        # greater than or equal to arr[i]
        arr[i] = lower_bound(temp, arr[i]) + 1
 
# Returns inversion count arr[0..n-1]
def getInvCount(arr, n):
 
    invcount = 0 # Initialize result
 
    # Convert arr to an array with values from 1 to n and
    # relative order of smaller and greater elements remains
    # same. For example, 7, -90, 100, 1 is converted to
    # 3, 1, 4 ,2
    convert(arr, n)
 
    # Create a BIT with size equal to maxElement+1 (Extra
    # one is used so that elements can be directly be
    # used as index)
    BIT = [0] * (n + 1)
 
    # Traverse all elements from right.
    for i in range(n - 1, -1, -1):
 
        # Get count of elements smaller than arr[i]
        invcount += getSum(BIT, arr[i] - 1)
 
        # Add current element to BIT
        updateBIT(BIT, n, arr[i], 1)
 
    return invcount
 
# Driver program
if __name__ == '__main__':
 
    arr = [8, 4, 2, 1]
    n = len(arr)
    print("Number of inversions are : ",getInvCount(arr, n))
 
# This code is contributed by mohit kumar 29

C#

// C# program to count inversions
// using Binary Indexed Tree
using System;
class GFG{
 
// Returns sum of arr[0..index].
// This function assumes that the
// array is preprocessed and partial
// sums of array elements are stored
// in BITree[].
static int getSum(int []BITree,
                  int index)
{
  // Initialize result
  int sum = 0;
 
  // Traverse ancestors of
  // BITree[index]
  while (index > 0)
  {
    // Add current element of
    // BITree to sum
    sum += BITree[index];
 
    // Move index to parent node
    // in getSum View
    index -= index & (-index);
  }
  return sum;
}
 
// Updates a node in Binary Index Tree
// (BITree) at given index in BITree. 
// The given value 'val' is added to
// BITree[i] and all of its ancestors
// in tree.
static void updateBIT(int []BITree, int n,
                      int index, int val)
{
  // Traverse all ancestors
  // and add 'val'
  while (index <= n)
  {
    // Add 'val' to current
    // node of BI Tree
    BITree[index] += val;
 
    // Update index to that of
    // parent in update View
    index += index & (-index);
  }
}
 
// Converts an array to an array
// with values from 1 to n and
// relative order of smaller and
// greater elements remains same. 
// For example, {7, -90, 100, 1}
// is converted to {3, 1, 4 ,2 }
static void convert(int []arr,
                    int n)
{
  // Create a copy of arrp[] in temp
  // and sort the temp array in
  // increasing order
  int []temp = new int[n];
   
  for (int i = 0; i < n; i++)
    temp[i] = arr[i];
  Array.Sort(temp);
 
  // Traverse all array elements
  for (int i = 0; i < n; i++)
  {
    // lower_bound() Returns pointer
    // to the first element greater
    // than or equal to arr[i]
    arr[i] =lower_bound(temp,0,
                        n, arr[i]) + 1;
  }
}
 
static int lower_bound(int[] a, int low,
                       int high, int element)
{
  while(low < high)
  {
    int middle = low +
                (high - low) / 2;
    if(element > a[middle])
      low = middle + 1;
    else
      high = middle;
  }
  return low;
}
 
// Returns inversion count
// arr[0..n-1]
static int getInvCount(int []arr,
                       int n)
{
  // Initialize result
  int invcount = 0;
 
  // Convert []arr to an array
  // with values from 1 to n and
  // relative order of smaller
  // and greater elements remains
  // same.  For example, {7, -90,
  // 100, 1} is converted to
  //  {3, 1, 4 ,2 }
  convert(arr, n);
 
  // Create a BIT with size equal
  // to maxElement+1 (Extra one is
  // used so that elements can be
  // directly be used as index)
  int []BIT = new int[n + 1];
   
  for (int i = 1; i <= n; i++)
    BIT[i] = 0;
 
  // Traverse all elements
  // from right.
  for (int i = n - 1; i >= 0; i--)
  {
    // Get count of elements
    // smaller than arr[i]
    invcount += getSum(BIT,
                       arr[i] - 1);
 
    // Add current element
    // to BIT
    updateBIT(BIT, n,
              arr[i], 1);
  }
 
  return invcount;
}
 
// Driver code
public static void Main(String[] args)
{
  int []arr = {8, 4, 2, 1};
  int n = arr.Length;
  Console.Write("Number of inversions are : " + 
                 getInvCount(arr, n));
}
}
 
// This code is contributed by Amit Katiyar

Javascript

<script>
// Javascript program to count inversions
// using Binary Indexed Tree
     
// Returns sum of arr[0..index].
// This function assumes that the
// array is preprocessed and partial
// sums of array elements are stored
// in BITree[].   
function getSum(BITree,index)
{
 
        // Initialize result
  let sum = 0;
  
  // Traverse ancestors of
  // BITree[index]
  while (index > 0)
  {
   
    // Add current element of
    // BITree to sum
    sum += BITree[index];
  
    // Move index to parent node
    // in getSum View
    index -= index & (-index);
  }
  return sum;
}
 
// Updates a node in Binary Index Tree
// (BITree) at given index in BITree.
// The given value 'val' is added to
// BITree[i] and all of its ancestors
// in tree.
function updateBIT(BITree,n,index,val)
{
 
    // Traverse all ancestors
  // and add 'val'
  while (index <= n)
  {
   
    // Add 'val' to current
    // node of BI Tree
    BITree[index] += val;
  
    // Update index to that of
    // parent in update View
    index += index & (-index);
  }
}
 
// Converts an array to an array
// with values from 1 to n and
// relative order of smaller and
// greater elements remains same.
// For example, {7, -90, 100, 1}
// is converted to {3, 1, 4 ,2 }
function convert(arr, n)
{
 
    // Create a copy of arrp[] in temp
  // and sort the temp array in
  // increasing order
  let temp = new Array(n);
    
  for (let i = 0; i < n; i++)
    temp[i] = arr[i];
  temp.sort(function(a, b){return a - b;});
  
  // Traverse all array elements
  for (let i = 0; i < n; i++)
  {
    // lower_bound() Returns pointer
    // to the first element greater
    // than or equal to arr[i]
    arr[i] =lower_bound(temp,0,
                        n, arr[i]) + 1;
  }
}
 
function lower_bound(a,low,high,element)
{
    while(low < high)
  {
    let middle = low +
                Math.floor((high - low) / 2);
    if(element > a[middle])
      low = middle + 1;
    else
      high = middle;
  }
  return low;
}
 
// Returns inversion count
// arr[0..n-1]
function getInvCount(arr,n)
{
    // Initialize result
  let invcount = 0;
  
  // Convert arr[] to an array
  // with values from 1 to n and
  // relative order of smaller
  // and greater elements remains
  // same.  For example, {7, -90,
  // 100, 1} is converted to
  //  {3, 1, 4 ,2 }
  convert(arr, n);
  
  // Create a BIT with size equal
  // to maxElement+1 (Extra one is
  // used so that elements can be
  // directly be used as index)
  let BIT = new Array(n + 1);
    
  for (let i = 1; i <= n; i++)
    BIT[i] = 0;
  
  // Traverse all elements
  // from right.
  for (let i = n - 1; i >= 0; i--)
  {
    // Get count of elements
    // smaller than arr[i]
    invcount += getSum(BIT,
                       arr[i] - 1);
  
    // Add current element to BIT
    updateBIT(BIT, n, arr[i], 1);
  }
  
  return invcount;
}
 
// Driver code
let arr=[8, 4, 2, 1];
let n = arr.length;
document.write("Number of inversions are : " +
                    getInvCount(arr, n));
 
    // This code is contributed by unknown2108
</script>
Producción

Number of inversions are : 6

Complejidad de tiempo: la función de actualización y la función getSum se ejecutan para O (log (n)). La función getSum debe ejecutarse para cada elemento de la array. Entonces, la complejidad del tiempo general es O (nlog (n)).
Espacio Auxiliar: O(n). 
El espacio requerido para el BIT es una array de tamaño n.

Este artículo es una contribución de Abhiraj Smit. Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *