📜  计算数组中的反转|第3组(使用BIT)

📅  最后修改于: 2021-05-25 09:05:46             🧑  作者: Mango

数组的反转计数指示–数组要排序的距离(或距离)。如果已对数组进行排序,则反转计数为0。如果以相反的顺序对数组进行排序,则反转计数为最大。
如果a [i]> a [j]且i 例子:

Input: arr[] = {8, 4, 2, 1}
Output: 6
Explanation: Given array has six inversions:
(8,4), (4,2), (8,2), (8,1), (4,1), (2,1).     


Input: arr[] = {3, 1, 2}
Output: 2
Explanation: Given array has two inversions:
(3,1), (3,2).

我们强烈建议您单击此处并进行实践,然后再继续解决方案。

我们已经讨论了以下解决反转计数的方法:

  1. 天真的和修改的合并排序
  2. 使用AVL树

我们建议您在进一步阅读此文章之前,先参考二进制索引树(BIT)。
使用大小为Θ(maxElement)的BIT的解决方案:

  • 方法:遍历数组,并为每个索引找到数组右侧的较小元素的数量。这可以使用BIT完成。对数组中所有索引的计数求和,然后打印总和。
  • BIT背景:
    1. 对于大小为n的数组arr [],BIT基本支持两种操作:
      1. 元素的总和,直到O(Log n)时间的arr [i]。
      2. 在O(Log n)时间中更新数组元素。
    2. BIT是使用数组实现的,并且以树的形式工作。请注意,有两种将BIT视为树的方法。
      1. 索引x的父级为“ x –(x&-x)”的求和运算。
      2. 索引x的父级为“ x +(x&-x)”的更新操作。
  • 算法:
    1. 创建一个BIT,以查找给定数量的BIT中较小元素的数量,以及变量result = 0
    2. 从头到尾遍历数组。
    3. 对于每个索引,请检查BIT中存在多少个小于当前元素的数字,并将其添加到结果中
    4. 要获取较小元素的数量,请使用BIT的getSum()。
    5. 在他的基本思想中,BIT表示为大小等于最大元素加一的数组。这样就可以将元素用作索引。
    6. 之后,我们通过执行更新操作将当前元素添加到BIT []中,该操作会将当前元素的计数从0更新为1,并因此更新BIT中当前元素的祖先(有关详细信息,请参见BIT中的update()) 。
  • 执行
C++
// C++ program to count inversions using Binary Indexed Tree
#include
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=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(1, maxElement + 1):
        BIT[i] = 0
    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
 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


C++
// C++ program to count inversions using Binary Indexed Tree
#include
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=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


  • 输出:
Number of inversions are : 6
  • 复杂度分析:
    • 时间复杂度:-更新函数和getSum函数的运行时间为O(log(maximumelement))。必须对数组中的每个元素运行getSum函数。因此,总体时间复杂度为:O(nlog(maximumelement))。
    • 辅助空间: O(maxElement),BIT所需的空间是最大元素大小的数组。

使用大小为Θ(n)的BIT更好的解决方案:

  • 方法:遍历数组,并为每个索引找到数组右侧的较小元素的数量。这可以使用BIT完成。对数组中所有索引的计数求和,然后打印总和。该方法保持不变,但是前一种方法的问题是它不适用于负数,因为索引不能为负。想法是将给定的数组转换为值从1到n的数组,较小和较大元素的相对顺序保持不变。
    例子:-
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. 
  • 算法:
    1. 创建一个BIT,以查找给定数量的BIT中较小元素的数量,以及变量result = 0
    2. 先前的解决方案不适用于包含负元素的数组。因此,将数组转换为包含元素相对编号的数组,即制作原始数组的副本,然后对数组的副本进行排序,并用已排序数组中相同元素的索引替换原始数组中的元素。
      例如,如果数组为{-3,2,0},则该数组将转换为{1,3,2}
    3. 从头到尾遍历数组。
    4. 对于每个索引,请检查BIT中存在多少个小于当前元素的数字,并将其添加到结果中
  • 执行:

C++

// C++ program to count inversions using Binary Indexed Tree
#include
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=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

Java脚本


  • 输出:
Number of inversions are : 6
  • 复杂度分析:
    • 时间复杂度: update函数和getSum函数的运行时间为O(log(n))。必须对数组中的每个元素运行getSum函数。因此,总体时间复杂度为O(nlog(n))。
    • 辅助空间: O(n)。
      BIT所需的空间是大小为n的数组。

如果您希望与行业专家一起参加现场课程,请参阅《 Geeks现场课程》和《 Geeks现场课程美国》。