Contando inversiones en una array usando un árbol de segmentos

Dada una array de enteros arr , la tarea es contar el número de inversiones en la array. 
Si A[i] > A[j] e i < j entonces el par (A[i], A[j]) es parte de una inversión.
Ejemplos: 
 

Entrada: arr[] = {8, 4, 2, 1} 
Salida: 6
Entrada: arr[] = {3, 1, 2} 
Salida:
 

Acercarse: 
 

  • Cree un árbol de segmentos en el que cada Node represente los números totales presentes en el rango de ese Node.
  • Digamos que el rango de cualquier Node es [i, j], entonces el Node contendrá el recuento de números que son mayores o iguales que i y menores o iguales que j.
  • Los Nodes de hoja solo serán 1 o 0, ya que el rango del Node será 1.
  • Itere a través de la array, deje que el número presente en el índice i sea a[i]. Encontraremos cuántos números están presentes en el árbol de segmentos en el rango [a[i]+1, max] donde max es el elemento máximo de la array y lo agregaremos a la variable de respuesta.
  • Luego insertaremos ese número en el árbol de segmentos y continuaremos hasta el último índice de la array. De esta manera, para cada elemento, estamos sumando los números que aparecen antes de ese elemento y son mayores que ese elemento, es decir, forman un par de inversión.

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

C++

// 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;
}

Java

// Java program to count the inversions
// present in the array using segment tree
import 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

# Python3 program to count the inversions
# present in the array using segment tree
 
# Function to update segment tree
# i.e. to insert the element
def 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 code
if __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

C#

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

Javascript

<script>
 
// JavaScript program to count the inversions
// present in the array using segment tree
 
 // Function to update segment tree
  // i.e. to insert the element
function 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>
Producción: 

6

 

Publicación traducida automáticamente

Artículo escrito por imdhruvgupta 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 *