Algorithm 数组中的倒计数

Algorithm 数组中的倒计数,algorithm,Algorithm,我正在设计一个算法来完成以下工作:给定数组A[1…n],对于每个IA[j]。我使用合并排序并将数组A复制到数组B,然后比较这两个数组,但是我很难看到如何使用它来找到反转数。任何提示或帮助都将不胜感激。简单的O(n^2)答案是使用嵌套循环,并为每个反转增加一个计数器 int counter = 0; for(int i = 0; i < n - 1; i++) { for(int j = i+1; j < n; j++) { if( A[i] >

我正在设计一个算法来完成以下工作:给定数组
A[1…n]
,对于每个
I
,找到所有的反转对,使得
A[I]>A[j]
。我使用合并排序并将数组A复制到数组B,然后比较这两个数组,但是我很难看到如何使用它来找到反转数。任何提示或帮助都将不胜感激。

简单的O(n^2)答案是使用嵌套循环,并为每个反转增加一个计数器

int counter = 0;

for(int i = 0; i < n - 1; i++)
{
    for(int j = i+1; j < n; j++)
    {
        if( A[i] > A[j] )
        {
            counter++;
        }
    }
}

return counter;
int计数器=0;
对于(int i=0;iA[j])
{
计数器++;
}
}
}
返回计数器;
现在我想你想要一个更有效的解决方案,我会考虑的。

我通过以下方法在O(n*logn)时间内找到了它

  • 合并排序数组A并创建副本(数组B)
  • 以A[1]为例,通过二进制搜索找到它在排序数组B中的位置。该元素的反转数将比其在B中位置的索引数少一个,因为在A的第一个元素之后出现的每一个较低的数字都将是反转数

    def binarySearch(alist, item):
        first = 0
        last = len(alist) - 1
        found = False
    
        while first <= last and not found:
            midpoint = (first + last)//2
            if alist[midpoint] == item:
                return midpoint
            else:
                if item < alist[midpoint]:
                    last = midpoint - 1
                else:
                    first = midpoint + 1
    
    def solution(A):
    
        B = list(A)
        B.sort()
        inversion_count = 0
        for i in range(len(A)):
            j = binarySearch(B, A[i])
            while B[j] == B[j - 1]:
                if j < 1:
                    break
                j -= 1
    
            inversion_count += j
            B.pop(j)
    
        if inversion_count > 1000000000:
            return -1
        else:
            return inversion_count
    
    print solution([4, 10, 11, 1, 3, 9, 10])
    
    2a。将反转数累加到计数器变量num_反转

    2b。从阵列A和阵列B中的相应位置删除A[1]

  • 从步骤2重新运行,直到A中没有更多元素
  • 下面是这个算法的一个运行示例。原始数组A=(6,9,1,14,8,12,3,2)

    1:合并排序并复制到数组B

    B=(1,2,3,6,8,9,12,14)

    2:进行[1]和二进制搜索,在数组B中找到它

    A[1]=6

    B=(1,2,3,6,8,9,12,14)

    6位于阵列B的第4个位置,因此有3个反转。我们之所以知道这一点,是因为6位于数组A中的第一个位置,因此随后出现在数组A中的任何低值元素的索引都是j>i(因为在本例中i是1)

    2.b:从数组A中删除A[1],也从数组b中相应的位置删除A[1](粗体元素被删除)

    A=(6,9,1,14,8,12,3,2)=(9,1,14,8,12,3,2)

    B=(1,2,3,6,8,9,12,14)=(1,2,3,8,9,12,14)

    3:在新的A和B阵列上从步骤2重新运行

    A[1]=9

    B=(1,2,3,8,9,12,14)

    9现在位于阵列B的第5个位置,因此有4个反转。我们之所以知道这一点,是因为9位于数组A的第一个位置,因此随后出现的任何较低值元素的索引都是j>i(因为在本例中i也是1)。 从数组A中删除A[1],也从数组B中相应的位置删除A[1](粗体元素已删除)

    A=(9,1,14,8,12,3,2)=(1,14,8,12,3,2)

    B=(1,2,3,8,9,12,14)=(1,2,3,8,12,14)

    循环完成后,继续此步骤将为我们提供阵列A的反转总数

    步骤1(合并排序)需要O(n*logn)才能执行。 步骤2将执行n次,每次执行时将执行一个二进制搜索,该搜索需要O(logn)来运行总共O(n*logn)。因此,总运行时间将是O(n*logn)+O(n*logn)=O(n*logn)


    谢谢你的帮助。在一张纸上写出样本数组确实有助于将问题形象化。

    实际上,对于家庭作业,我有一个类似的问题。我被限制它必须有O(nlogn)效率

    我使用了您提出的使用Mergesort的想法,因为它已经具有正确的效率。我刚刚在合并函数中插入了一些代码,基本上是: 无论何时,只要将右侧数组中的一个数字添加到输出数组中,我就会将左侧数组中剩余的数字添加到反转总数中

    这对我来说很有意义,因为我已经考虑够了。您正在计算在任何数字之前有多少次出现更大的数字

    hth.

    查看以下内容:

    我希望它能给你正确的答案

    • 2-3反转部分(d)
    • 它的运行时间是O(nlogn)
      • 下面是java中的O(n logn)解决方案

        long merge(int[] arr, int[] left, int[] right) {
            int i = 0, j = 0, count = 0;
            while (i < left.length || j < right.length) {
                if (i == left.length) {
                    arr[i+j] = right[j];
                    j++;
                } else if (j == right.length) {
                    arr[i+j] = left[i];
                    i++;
                } else if (left[i] <= right[j]) {
                    arr[i+j] = left[i];
                    i++;                
                } else {
                    arr[i+j] = right[j];
                    count += left.length-i;
                    j++;
                }
            }
            return count;
        }
        
        long invCount(int[] arr) {
            if (arr.length < 2)
                return 0;
        
            int m = (arr.length + 1) / 2;
            int left[] = Arrays.copyOfRange(arr, 0, m);
            int right[] = Arrays.copyOfRange(arr, m, arr.length);
        
            return invCount(left) + invCount(right) + merge(arr, left, right);
        }
        
        长合并(int[]arr,int[]left,int[]right){
        int i=0,j=0,count=0;
        而(i}else if(left[i]注意杰弗里·欧文的答案是错误的

        一个数组中的反转数是为了对数组进行排序而必须移动的总距离元素数的一半。因此,可以通过对数组进行排序,保持产生的置换p[i],然后计算abs(p[i]-i)/2之和来计算反转数。这需要O(n logn)时间,这是最优的

        在中给出了另一种方法。该方法相当于max(0,p[i]-i)之和,它等于abs(p[i]-i])/2之和,因为向左移动的总距离元素等于向右移动的总距离元素


        以序列{3,2,1}为例。有三个倒数:(3,2),(3,1),(2,1),所以倒数是3。然而,根据引用的方法,答案应该是2。

        因为这是一个老问题,我将用C提供我的答案

        #include <stdio.h>
        
        int count = 0;
        int inversions(int a[], int len);
        void mergesort(int a[], int left, int right);
        void merge(int a[], int left, int mid, int right);
        
        int main() {
          int a[] = { 1, 5, 2, 4, 0 };
          printf("%d\n", inversions(a, 5));
        }
        
        int inversions(int a[], int len) {
          mergesort(a, 0, len - 1);
          return count;
        }
        
        void mergesort(int a[], int left, int right) {
          if (left < right) {
             int mid = (left + right) / 2;
             mergesort(a, left, mid);
             mergesort(a, mid + 1, right);
             merge(a, left, mid, right);
          }
        }
        
        void merge(int a[], int left, int mid, int right) {
          int i = left;
          int j = mid + 1;
          int k = 0;
          int b[right - left + 1];
          while (i <= mid && j <= right) {
             if (a[i] <= a[j]) {
               b[k++] = a[i++];
             } else {
               printf("right element: %d\n", a[j]);
               count += (mid - i + 1);
               printf("new count: %d\n", count);
               b[k++] = a[j++];
             }
          }
          while (i <= mid)
            b[k++] = a[i++];
          while (j <= right)
            b[k++] = a[j++];
          for (i = left, k = 0; i <= right; i++, k++) {
            a[i] = b[k];
          }
        }
        
        #包括
        整数计数=0;
        整数反转(整数a[],整数len);
        void mergesort(int a[],int left,int right);
        无效合并(int a[],int left,int mid,int right);
        int main(){
        inta[]={1,5,2,4,0};
        printf(“%d\n”,反转(a,5));
        }
        整数反转(整数a[],整数len){
        合并排序(a,0,len-1);
        返回计数;
        }
        无效合并排序(int a[],int左,int右){
        if(左<右){
        int mid=(左+右)/2;
        合并排序(a、左、中);
        合并排序(a,中间+1,右);
        梅尔
        
        #include <stdio.h>
        #include <stdlib.h>
        
        int  _mergeSort(int arr[], int temp[], int left, int right);
        int merge(int arr[], int temp[], int left, int mid, int right);
        
        /* This function sorts the input array and returns the
           number of inversions in the array */
        int mergeSort(int arr[], int array_size)
        {
            int *temp = (int *)malloc(sizeof(int)*array_size);
            return _mergeSort(arr, temp, 0, array_size - 1);
        }
        
        /* An auxiliary recursive function that sorts the input array and
          returns the number of inversions in the array. */
        int _mergeSort(int arr[], int temp[], int left, int right)
        {
          int mid, inv_count = 0;
          if (right > left)
          {
            /* Divide the array into two parts and call _mergeSortAndCountInv()
               for each of the parts */
            mid = (right + left)/2;
        
            /* Inversion count will be sum of inversions in left-part, right-part
              and number of inversions in merging */
            inv_count  = _mergeSort(arr, temp, left, mid);
            inv_count += _mergeSort(arr, temp, mid+1, right);
        
            /*Merge the two parts*/
            inv_count += merge(arr, temp, left, mid+1, right);
          }
          return inv_count;
        }
        
        /* This funt merges two sorted arrays and returns inversion count in
           the arrays.*/
        int merge(int arr[], int temp[], int left, int mid, int right)
        {
          int i, j, k;
          int inv_count = 0;
        
          i = left; /* i is index for left subarray*/
          j = mid;  /* i is index for right subarray*/
          k = left; /* i is index for resultant merged subarray*/
          while ((i <= mid - 1) && (j <= right))
          {
            if (arr[i] <= arr[j])
            {
              temp[k++] = arr[i++];
            }
            else
            {
              temp[k++] = arr[j++];
        
             /*this is tricky -- see above explanation/diagram for merge()*/
              inv_count = inv_count + (mid - i);
            }
          }
        
          /* Copy the remaining elements of left subarray
           (if there are any) to temp*/
          while (i <= mid - 1)
            temp[k++] = arr[i++];
        
          /* Copy the remaining elements of right subarray
           (if there are any) to temp*/
          while (j <= right)
            temp[k++] = arr[j++];
        
          /*Copy back the merged elements to original array*/
          for (i=left; i <= right; i++)
            arr[i] = temp[i];
        
          return inv_count;
        }
        
        /* Driver progra to test above functions */
        int main(int argv, char** args)
        {
          int arr[] = {1, 20, 6, 4, 5};
          printf(" Number of inversions are %d \n", mergeSort(arr, 5));
          getchar();
          return 0;
        }
        
        Node { 
            int data;
            Node* left, *right;
            int rightSubTreeSize;
        
            Node(int data) { 
                rightSubTreeSize = 0;
            }   
        };
        
        Node* root = null;
        int totCnt = 0;
        for(i = 0; i < n; ++i) { 
            Node* p = new Node(a[i]);
            if(root == null) { 
                root = p;
                continue;
            } 
        
            Node* q = root;
            int curCnt = 0;
            while(q) { 
                if(p->data <= q->data) { 
                    curCnt += 1 + q->rightSubTreeSize;
                    if(q->left) { 
                        q = q->left;
                    } else { 
                        q->left = p;
                        break;
                    }
                } else { 
                    q->rightSubTreeSize++;
                    if(q->right) { 
                        q = q->right;
                    } else { 
                        q->right = p;
                        break;
                    }
                }
            }
        
            totCnt += curCnt;
          }
          return totCnt;
        
        public static int mergeSort(int[] a, int p, int r)
        {
            int countInversion = 0;
            if(p < r)
            {
                int q = (p + r)/2;
                countInversion = mergeSort(a, p, q);
                countInversion += mergeSort(a, q+1, r);
                countInversion += merge(a, p, q, r);
            }
            return countInversion;
        }
        
        public static int merge(int[] a, int p, int q, int r)
        {
            //p=0, q=1, r=3
            int countingInversion = 0;
            int n1 = q-p+1;
            int n2 = r-q;
            int[] temp1 = new int[n1+1];
            int[] temp2 = new int[n2+1];
            for(int i=0; i<n1; i++) temp1[i] = a[p+i];
            for(int i=0; i<n2; i++) temp2[i] = a[q+1+i];
        
            temp1[n1] = Integer.MAX_VALUE;
            temp2[n2] = Integer.MAX_VALUE;
            int i = 0, j = 0;
        
            for(int k=p; k<=r; k++)
            {
                if(temp1[i] <= temp2[j])
                {
                    a[k] = temp1[i];
                    i++;
                }
                else
                {
                    a[k] = temp2[j];
                    j++;
                    countingInversion=countingInversion+(n1-i); 
                }
            }
            return countingInversion;
        }
        public static void main(String[] args)
        {
            int[] a = {1, 20, 6, 4, 5};
            int countInversion = mergeSort(a, 0, a.length-1);
            System.out.println(countInversion);
        }
        
        #include <algorithm>
        
        vector<int> merge(vector<int>left, vector<int>right, int &counter)
        {
        
            vector<int> result;
        
            vector<int>::iterator it_l=left.begin();
            vector<int>::iterator it_r=right.begin();
        
            int index_left=0;
        
            while(it_l!=left.end() || it_r!=right.end())
            {
        
                // the following is true if we are finished with the left vector 
                // OR if the value in the right vector is the smaller one.
        
                if(it_l==left.end() || (it_r!=right.end() && *it_r<*it_l) )
                {
                    result.push_back(*it_r);
                    it_r++;
        
                    // increase inversion counter
                    counter+=left.size()-index_left;
                }
                else
                {
                    result.push_back(*it_l);
                    it_l++;
                    index_left++;
        
                }
            }
        
            return result;
        }
        
        vector<int> merge_sort_and_count(vector<int> A, int &counter)
        {
        
            int N=A.size();
            if(N==1)return A;
        
            vector<int> left(A.begin(),A.begin()+N/2);
            vector<int> right(A.begin()+N/2,A.end());
        
            left=merge_sort_and_count(left,counter);
            right=merge_sort_and_count(right,counter);
        
        
            return merge(left, right, counter);
        
        }
        
        inversionNumber <- function(x){
            mergeSort <- function(x){
                if(length(x) == 1){
                    inv <- 0
                } else {
                    n <- length(x)
                    n1 <- ceiling(n/2)
                    n2 <- n-n1
                    y1 <- mergeSort(x[1:n1])
                    y2 <- mergeSort(x[n1+1:n2])
                    inv <- y1$inversions + y2$inversions
                    x1 <- y1$sortedVector
                    x2 <- y2$sortedVector
                    i1 <- 1
                    i2 <- 1
                    while(i1+i2 <= n1+n2+1){
                        if(i2 > n2 || i1 <= n1 && x1[i1] <= x2[i2]){
                            x[i1+i2-1] <- x1[i1]
                            i1 <- i1 + 1
                        } else {
                            inv <- inv + n1 + 1 - i1
                            x[i1+i2-1] <- x2[i2]
                            i2 <- i2 + 1
                        }
                    }
                }
                return (list(inversions=inv,sortedVector=x))
            }
            r <- mergeSort(x)
            return (r$inversions)
        }
        
        import bisect
        def solution(A):
            sorted_left = []
            res = 0
            for i in xrange(1, len(A)):
                bisect.insort_left(sorted_left, A[i-1])
                # i is also the length of sorted_left
                res += (i - bisect.bisect(sorted_left, A[i]))
            return res
        
        def count_inversions(a):
          res = 0
          counts = [0]*(len(a)+1)
          rank = { v : i+1 for i, v in enumerate(sorted(a)) }
          for x in reversed(a):
            i = rank[x] - 1
            while i:
              res += counts[i]
              i -= i & -i
            i = rank[x]
            while i <= len(a):
              counts[i] += 1
              i += i & -i
          return res
        
            public class FindInversions {
        
            public static int solution(int[] input) {
                if (input == null)
                    return 0;
                int[] helper = new int[input.length];
                return mergeSort(0, input.length - 1, input, helper);
            }
        
            public static int mergeSort(int low, int high, int[] input, int[] helper) {
                int inversionCount = 0;
                if (low < high) {
                    int medium = low + (high - low) / 2;
                    inversionCount += mergeSort(low, medium, input, helper);
                    inversionCount += mergeSort(medium + 1, high, input, helper);
                    inversionCount += merge(low, medium, high, input, helper);
                }
                return inversionCount;
            }
        
            public static int merge(int low, int medium, int high, int[] input, int[] helper) {
                int inversionCount = 0;
        
                for (int i = low; i <= high; i++)
                    helper[i] = input[i];
        
                int i = low;
                int j = medium + 1;
                int k = low;
        
                while (i <= medium && j <= high) {
                    if (helper[i] <= helper[j]) {
                        input[k] = helper[i];
                        i++;
                    } else {
                        input[k] = helper[j];
                        // the number of elements in the first half which the j element needs to jump over.
                        // there is an inversion between each of those elements and j.
                        inversionCount += (medium + 1 - i);
                        j++;
                    }
                    k++;
                }
        
                // finish writing back in the input the elements from the first part
                while (i <= medium) {
                    input[k] = helper[i];
                    i++;
                    k++;
                }
                return inversionCount;
            }
        
        }
        
        def solution(t)
            sorted, inversion_count = sort_inversion_count(t)
            return inversion_count
        end
        
        def sort_inversion_count(t)
            midpoint = t.length / 2
            left_half = t[0...midpoint]
            right_half = t[midpoint..t.length]
        
            if midpoint == 0
                return t, 0
            end
        
            sorted_left_half, left_half_inversion_count = sort_inversion_count(left_half)
            sorted_right_half, right_half_inversion_count = sort_inversion_count(right_half)
        
            sorted = []
            inversion_count = 0
            while sorted_left_half.length > 0 or sorted_right_half.length > 0
                if sorted_left_half.empty?
                    sorted.push sorted_right_half.shift
                elsif sorted_right_half.empty?
                    sorted.push sorted_left_half.shift
                else
                    if sorted_left_half[0] > sorted_right_half[0]
                        inversion_count += sorted_left_half.length
                        sorted.push sorted_right_half.shift
                    else
                        sorted.push sorted_left_half.shift
                    end
                end
            end
        
            return sorted, inversion_count + left_half_inversion_count + right_half_inversion_count
        end
        
        require "minitest/autorun"
        
        class TestCodility < Minitest::Test
            def test_given_example
                a = [-1, 6, 3, 4, 7, 4]
                assert_equal solution(a), 4
            end
        
            def test_empty
                a = []
                assert_equal solution(a), 0
            end
        
            def test_singleton
                a = [0]
                assert_equal solution(a), 0
            end
        
            def test_none
                a = [1,2,3,4,5,6,7]
                assert_equal solution(a), 0
            end
        
            def test_all
                a = [5,4,3,2,1]
                assert_equal solution(a), 10
            end
        
            def test_clones
                a = [4,4,4,4,4,4]
                assert_equal solution(a), 0
            end
        end
        
        /**
        *array sorting needed to verify if first arrays n'th element is greater than sencond arrays
        *some element then all elements following n will do the same
        */
        #include<stdio.h>
        #include<iostream>
        using namespace std;
        int countInversions(int array[],int size);
        int merge(int arr1[],int size1,int arr2[],int size2,int[]);
        int main()
        {
            int array[] = {2, 4, 1, 3, 5};
            int size = sizeof(array) / sizeof(array[0]);
            int x = countInversions(array,size);
            printf("number of inversions = %d",x);
        }
        
        int countInversions(int array[],int size)
        {
            if(size > 1 )
            {
            int mid = size / 2;
            int count1 = countInversions(array,mid);
            int count2 = countInversions(array+mid,size-mid);
            int temp[size];
            int count3 = merge(array,mid,array+mid,size-mid,temp);
            for(int x =0;x<size ;x++)
            {
                array[x] = temp[x];
            }
            return count1 + count2 + count3;
            }else{
                return 0;
            }
        }
        
        int merge(int arr1[],int size1,int arr2[],int size2,int temp[])
        {
            int count  = 0;
            int a = 0;
            int b = 0;
            int c = 0;
            while(a < size1 && b < size2)
            {
                if(arr1[a] < arr2[b])
                {
                    temp[c] = arr1[a];
                    c++;
                    a++;
                }else{
                    temp[c] = arr2[b];
                    b++;
                    c++;
                    count = count + size1 -a;
                }
            }
        
            while(a < size1)
            {
                temp[c] = arr1[a];
                c++;a++;
            }
        
        while(b < size2)
            {
                temp[c] = arr2[b];
                c++;b++;
            }
        
            return count;
        }
        
        sub sort_and_count {
            my ($arr, $n) = @_;
            return ($arr, 0) unless $n > 1;
        
            my $mid = $n % 2 == 1 ? ($n-1)/2 : $n/2;
            my @left = @$arr[0..$mid-1];
            my @right = @$arr[$mid..$n-1];
        
            my ($sleft, $x) = sort_and_count( \@left, $mid );
            my ($sright, $y) = sort_and_count( \@right, $n-$mid);
            my ($merged, $z) = merge_and_countsplitinv( $sleft, $sright, $n );
        
            return ($merged, $x+$y+$z);
        }
        
        sub merge_and_countsplitinv {
            my ($left, $right, $n) = @_;
        
            my ($l_c, $r_c) = ($#$left+1, $#$right+1);
            my ($i, $j) = (0, 0);
            my @merged;
            my $inv = 0;
        
            for my $k (0..$n-1) {
                if ($i<$l_c && $j<$r_c) {
                    if ( $left->[$i] < $right->[$j]) {
                        push @merged, $left->[$i];
                        $i+=1;
                    } else {
                        push @merged, $right->[$j];
                        $j+=1;
                        $inv += $l_c - $i;
                    }
                } else {
                    if ($i>=$l_c) {
                        push @merged, @$right[ $j..$#$right ];
                    } else {
                        push @merged, @$left[ $i..$#$left ];
                    }
                    last;
                }
            }
        
            return (\@merged, $inv);
        }
        
        def merge(l1,l2):
            l = []
            # global count
            while l1 and l2:
                if l1[-1] <= l2[-1]:
                    l.append(l2.pop())
                else:
                    l.append(l1.pop())
                    # count += len(l2)
            l.reverse()
            return l1 + l2 + l
        
        def sort(l): 
            t = len(l) // 2
            return merge(sort(l[:t]), sort(l[t:])) if t > 0 else l
        
        count=0
        print(sort([5,1,2,4,9,3]), count)
        # [1, 2, 3, 4, 5, 9] 6
        
        def part(l):
            pivot=l[-1]
            small,big = [],[]
            count = big_count = 0
            for x in l:
                if x <= pivot:
                    small.append(x)
                    count += big_count
                else:
                    big.append(x)
                    big_count += 1
            return count,small,big
        
        def quick_count(l):
            if len(l)<2 : return 0
            count,small,big = part(l)
            small.pop()
            return count + quick_count(small) + quick_count(big)
        
        def count_inversions(a):
            n = a.size
            counts = np.arange(n) & -np.arange(n)  # The BIT
            ags = a.argsort(kind='mergesort')    
            return  BIT(ags,counts,n)
        
        @numba.njit
        def BIT(ags,counts,n):
            res = 0        
            for x in ags :
                i = x
                while i:
                    res += counts[i]
                    i -= i & -i
                i = x+1
                while i < n:
                    counts[i] -= 1
                    i += i & -i
            return  res  
        
        def binarySearch(alist, item):
            first = 0
            last = len(alist) - 1
            found = False
        
            while first <= last and not found:
                midpoint = (first + last)//2
                if alist[midpoint] == item:
                    return midpoint
                else:
                    if item < alist[midpoint]:
                        last = midpoint - 1
                    else:
                        first = midpoint + 1
        
        def solution(A):
        
            B = list(A)
            B.sort()
            inversion_count = 0
            for i in range(len(A)):
                j = binarySearch(B, A[i])
                while B[j] == B[j - 1]:
                    if j < 1:
                        break
                    j -= 1
        
                inversion_count += j
                B.pop(j)
        
            if inversion_count > 1000000000:
                return -1
            else:
                return inversion_count
        
        print solution([4, 10, 11, 1, 3, 9, 10])
        
        //Code
        #include <bits/stdc++.h>
        using namespace std;
        
        int main()
        {
            int i,n;
            cin >> n;
            int arr[n],inv[n];
            for(i=0;i<n;i++){
                cin >> arr[i];
            }
            vector<int> v;
            v.push_back(arr[n-1]);
            inv[n-1]=0;
            for(i=n-2;i>=0;i--){
                auto it = lower_bound(v.begin(),v.end(),arr[i]); 
                //calculating least element in vector v which is greater than arr[i]
                inv[i]=it-v.begin();
                //calculating distance from starting of vector
                v.insert(it,arr[i]);
                //inserting that element into vector v
            }
            for(i=0;i<n;i++){
                cout << inv[i] << " ";
            }
            cout << endl;
            return 0;
        }
        
        //INPUT     
        4
        2 1 4 3
        
        //OUTPUT    
        1 0 1 0
        
        //To calculate total inversion count just add up all the elements in output array
        
        public class TestInversionThruMergeSort {
            
            static int count =0;
        
            public static void main(String[] args) {
                int[] arr = {6, 9, 1, 14, 8, 12, 3, 2};
                
        
                partition(arr);
        
                for (int i = 0; i < arr.length; i++) {
        
                    System.out.println(arr[i]);
                }
                
                System.out.println("inversions are "+count);
        
            }
        
            public static void partition(int[] arr) {
        
                if (arr.length > 1) {
        
                    int mid = (arr.length) / 2;
                    int[] left = null;
        
                    if (mid > 0) {
                        left = new int[mid];
        
                        for (int i = 0; i < mid; i++) {
                            left[i] = arr[i];
                        }
                    }
        
                    int[] right = new int[arr.length - left.length];
        
                    if ((arr.length - left.length) > 0) {
                        int j = 0;
                        for (int i = mid; i < arr.length; i++) {
                            right[j] = arr[i];
                            ++j;
                        }
                    }
        
                    partition(left);
                    partition(right);
                    mergeToParent(left, right, arr);
                }
        
            }
        
            public static void mergeToParent(int[] left, int[] right, int[] parent) {
        
                int leftunPicked = 0;
                int rightunPicked = 0;
                int parentIndex = -1;
        
                while (rightunPicked < right.length && leftunPicked < left.length) {
        
                    if (left[leftunPicked] < right[rightunPicked]) {
                        parent[++parentIndex] = left[leftunPicked];
                        ++leftunPicked;
        
                    } else {
                        count = count + left.length-leftunPicked;
                        if ((rightunPicked < right.length)) {
                            parent[++parentIndex] = right[rightunPicked];
                            ++rightunPicked;
                        }
                    }
        
                }
        
                while (leftunPicked < left.length) {
                    parent[++parentIndex] = left[leftunPicked];
                    ++leftunPicked;
                }
        
                while (rightunPicked < right.length) {
                    parent[++parentIndex] = right[rightunPicked];
                    ++rightunPicked;
                }
        
            }
        
        }
        
        import java.util.ArrayList;
        import java.util.Arrays;
        import java.util.Collections;
        import java.util.Iterator;
        import java.util.List;
        
        
        public class TestInversion {
        
            public static void main(String[] args) {
                
                Integer [] arr1 = {6, 9, 1, 14, 8, 12, 3, 2};
                
                List<Integer> arr = new ArrayList(Arrays.asList(arr1));
                List<Integer> sortArr = new ArrayList<Integer>();
                
                for(int i=0;i<arr.size();i++){
                    sortArr.add(arr.get(i));
                 
                }
                
                    
                Collections.sort(sortArr);
                
                int inversion = 0;
                
                Iterator<Integer> iter = arr.iterator();
                
                while(iter.hasNext()){
                    
                    Integer el = (Integer)iter.next();
                    int index = sortArr.indexOf(el);
                    
                    if(index+1 > 1){
                        inversion = inversion + ((index+1)-1);
                    }
                    
                    //iter.remove();
                    sortArr.remove(el);
                    
                }
                
                System.out.println("Inversions are "+inversion);
                
                
                
        
            }
        
        
        }
        
        maxPossibleInversions = (n * (n-1) ) / 2
        
        var arr = [6,5,4,3,2,1]; // Sample input array
        
        var inversionCount = 0;
        
        function mergeSort(arr) {
            if(arr.length == 1)
                return arr;
        
            if(arr.length > 1) {
                let breakpoint = Math.ceil((arr.length/2));
                // Left list starts with 0, breakpoint-1
                let leftList = arr.slice(0,breakpoint);
                // Right list starts with breakpoint, length-1
                let rightList = arr.slice(breakpoint,arr.length);
        
                // Make a recursive call
                leftList = mergeSort(leftList);
                rightList = mergeSort(rightList);
        
                var a = merge(leftList,rightList);
                return a;
            }
        }
        
        function merge(leftList,rightList) {
            let result = [];
            while(leftList.length && rightList.length) {
                /**
                 * The shift() method removes the first element from an array
                 * and returns that element. This method changes the length
                 * of the array.
                 */
                if(leftList[0] <= rightList[0]) {
                    result.push(leftList.shift());
                }else{
                    inversionCount += leftList.length;
                    result.push(rightList.shift());
                }
            }
        
            while(leftList.length)
                result.push(leftList.shift());
        
            while(rightList.length)
                result.push(rightList.shift());
        
            console.log(result);
            return result;
        }
        
        mergeSort(arr);
        console.log('Number of inversions: ' + inversionCount);
        
        nSwaps += mid + 1 - iL 
        
        def count_inversions(a):
            total = 0
            counts = [0] * len(a)
            rank = {v: i for i, v in enumerate(sorted(a))}
            for u in reversed(a):
                i = rank[u]
                total += sum(counts[:i])
                counts[i] += 1
            return total
        
        seq = [15, 14, 11, 12, 10, 13]
        b = [t[::-1] for t in enumerate(seq)]
        print(b)
        b.sort()
        print(b)
        
        [(15, 0), (14, 1), (11, 2), (12, 3), (10, 4), (13, 5)]
        [(10, 4), (11, 2), (12, 3), (13, 5), (14, 1), (15, 0)]
        
        print(sorted(range(len(seq)), key=lambda k: seq[k]))
        
        [4, 2, 3, 5, 1, 0]
        
        sorted(range(len(seq)), key=seq.__getitem__)
        
        count_inversions speed test results
        
        Size = 5, hi = 2, 4096 loops
        ltree_count_PM2R         : 0.04871, 0.04872, 0.04876
        bruteforce_loops_PM2R    : 0.05696, 0.05700, 0.05776
        solution_TimBabych       : 0.05760, 0.05822, 0.05943
        solutionE_TimBabych      : 0.06642, 0.06704, 0.06760
        bruteforce_sum_PM2R      : 0.07523, 0.07545, 0.07563
        perm_sum_PM2R            : 0.09873, 0.09875, 0.09935
        rank_sum_PM2R            : 0.10449, 0.10463, 0.10468
        solution_python          : 0.13034, 0.13061, 0.13221
        fenwick_inline_PM2R      : 0.14323, 0.14610, 0.18802
        perm_radixR_PM2R         : 0.15146, 0.15203, 0.15235
        merge_count_BM           : 0.16179, 0.16267, 0.16467
        perm_radixI_PM2R         : 0.16200, 0.16202, 0.16768
        perm_fenwick_PM2R        : 0.16887, 0.16920, 0.17075
        merge_PM2R               : 0.18262, 0.18271, 0.18418
        count_inversions_NiklasB : 0.19183, 0.19279, 0.20388
        count_inversion_mkso     : 0.20060, 0.20141, 0.20398
        inv_cnt_ZheHu            : 0.20815, 0.20841, 0.20906
        fenwick_PM2R             : 0.22109, 0.22137, 0.22379
        reversePairs_nomanpouigt : 0.29620, 0.29689, 0.30293
        Value: 5
        
        Size = 10, hi = 5, 2048 loops
        solution_TimBabych       : 0.05954, 0.05989, 0.05991
        solutionE_TimBabych      : 0.05970, 0.05972, 0.05998
        perm_sum_PM2R            : 0.07517, 0.07519, 0.07520
        ltree_count_PM2R         : 0.07672, 0.07677, 0.07684
        bruteforce_loops_PM2R    : 0.07719, 0.07724, 0.07817
        rank_sum_PM2R            : 0.08587, 0.08823, 0.08864
        bruteforce_sum_PM2R      : 0.09470, 0.09472, 0.09484
        solution_python          : 0.13126, 0.13154, 0.13185
        perm_radixR_PM2R         : 0.14239, 0.14320, 0.14474
        perm_radixI_PM2R         : 0.14632, 0.14669, 0.14679
        fenwick_inline_PM2R      : 0.16796, 0.16831, 0.17030
        perm_fenwick_PM2R        : 0.18189, 0.18212, 0.18638
        merge_count_BM           : 0.19816, 0.19870, 0.19948
        count_inversions_NiklasB : 0.21807, 0.22031, 0.22215
        merge_PM2R               : 0.22037, 0.22048, 0.26106
        fenwick_PM2R             : 0.24290, 0.24314, 0.24744
        count_inversion_mkso     : 0.24895, 0.24899, 0.25205
        inv_cnt_ZheHu            : 0.26253, 0.26259, 0.26590
        reversePairs_nomanpouigt : 0.35711, 0.35762, 0.35973
        Value: 20
        
        Size = 20, hi = 10, 1024 loops
        solutionE_TimBabych      : 0.05687, 0.05696, 0.05720
        solution_TimBabych       : 0.06126, 0.06151, 0.06168
        perm_sum_PM2R            : 0.06875, 0.06906, 0.07054
        rank_sum_PM2R            : 0.07988, 0.07995, 0.08002
        ltree_count_PM2R         : 0.11232, 0.11239, 0.11257
        bruteforce_loops_PM2R    : 0.12553, 0.12584, 0.12592
        solution_python          : 0.13472, 0.13540, 0.13694
        bruteforce_sum_PM2R      : 0.15820, 0.15849, 0.16021
        perm_radixI_PM2R         : 0.17101, 0.17148, 0.17229
        perm_radixR_PM2R         : 0.17891, 0.18087, 0.18366
        perm_fenwick_PM2R        : 0.20554, 0.20708, 0.21412
        fenwick_inline_PM2R      : 0.21161, 0.21163, 0.22047
        merge_count_BM           : 0.24125, 0.24261, 0.24565
        count_inversions_NiklasB : 0.25712, 0.25754, 0.25778
        merge_PM2R               : 0.26477, 0.26566, 0.31297
        fenwick_PM2R             : 0.28178, 0.28216, 0.29069
        count_inversion_mkso     : 0.30286, 0.30290, 0.30652
        inv_cnt_ZheHu            : 0.32024, 0.32041, 0.32447
        reversePairs_nomanpouigt : 0.45812, 0.45822, 0.46172
        Value: 98
        
        Size = 40, hi = 20, 512 loops
        solutionE_TimBabych      : 0.05784, 0.05787, 0.05958
        solution_TimBabych       : 0.06452, 0.06475, 0.06479
        perm_sum_PM2R            : 0.07254, 0.07261, 0.07263
        rank_sum_PM2R            : 0.08537, 0.08540, 0.08572
        ltree_count_PM2R         : 0.11744, 0.11749, 0.11792
        solution_python          : 0.14262, 0.14285, 0.14465
        perm_radixI_PM2R         : 0.18774, 0.18776, 0.18922
        perm_radixR_PM2R         : 0.19425, 0.19435, 0.19609
        bruteforce_loops_PM2R    : 0.21500, 0.21511, 0.21686
        perm_fenwick_PM2R        : 0.23338, 0.23375, 0.23674
        fenwick_inline_PM2R      : 0.24947, 0.24958, 0.25189
        bruteforce_sum_PM2R      : 0.27627, 0.27646, 0.28041
        merge_count_BM           : 0.28059, 0.28128, 0.28294
        count_inversions_NiklasB : 0.28557, 0.28759, 0.29022
        merge_PM2R               : 0.29886, 0.29928, 0.30317
        fenwick_PM2R             : 0.30241, 0.30259, 0.35237
        count_inversion_mkso     : 0.34252, 0.34356, 0.34441
        inv_cnt_ZheHu            : 0.37468, 0.37569, 0.37847
        reversePairs_nomanpouigt : 0.50725, 0.50770, 0.50943
        Value: 369
        
        Size = 80, hi = 40, 256 loops
        solutionE_TimBabych      : 0.06339, 0.06373, 0.06513
        solution_TimBabych       : 0.06984, 0.06994, 0.07009
        perm_sum_PM2R            : 0.09171, 0.09172, 0.09186
        rank_sum_PM2R            : 0.10468, 0.10474, 0.10500
        ltree_count_PM2R         : 0.14416, 0.15187, 0.18541
        solution_python          : 0.17415, 0.17423, 0.17451
        perm_radixI_PM2R         : 0.20676, 0.20681, 0.20936
        perm_radixR_PM2R         : 0.21671, 0.21695, 0.21736
        perm_fenwick_PM2R        : 0.26197, 0.26252, 0.26264
        fenwick_inline_PM2R      : 0.28111, 0.28249, 0.28382
        count_inversions_NiklasB : 0.31746, 0.32448, 0.32451
        merge_count_BM           : 0.31964, 0.33842, 0.35276
        merge_PM2R               : 0.32890, 0.32941, 0.33322
        fenwick_PM2R             : 0.34355, 0.34377, 0.34873
        count_inversion_mkso     : 0.37689, 0.37698, 0.38079
        inv_cnt_ZheHu            : 0.42923, 0.42941, 0.43249
        bruteforce_loops_PM2R    : 0.43544, 0.43601, 0.43902
        bruteforce_sum_PM2R      : 0.52106, 0.52160, 0.52531
        reversePairs_nomanpouigt : 0.57805, 0.58156, 0.58252
        Value: 1467
        
        Size = 160, hi = 80, 128 loops
        solutionE_TimBabych      : 0.06766, 0.06784, 0.06963
        solution_TimBabych       : 0.07433, 0.07489, 0.07516
        perm_sum_PM2R            : 0.13143, 0.13175, 0.13179
        rank_sum_PM2R            : 0.14428, 0.14440, 0.14922
        solution_python          : 0.20072, 0.20076, 0.20084
        ltree_count_PM2R         : 0.20314, 0.20583, 0.24776
        perm_radixI_PM2R         : 0.23061, 0.23078, 0.23525
        perm_radixR_PM2R         : 0.23894, 0.23915, 0.24234
        perm_fenwick_PM2R        : 0.30984, 0.31181, 0.31503
        fenwick_inline_PM2R      : 0.31933, 0.32680, 0.32722
        merge_count_BM           : 0.36003, 0.36387, 0.36409
        count_inversions_NiklasB : 0.36796, 0.36814, 0.37106
        merge_PM2R               : 0.36847, 0.36848, 0.37127
        fenwick_PM2R             : 0.37833, 0.37847, 0.38095
        count_inversion_mkso     : 0.42746, 0.42747, 0.43184
        inv_cnt_ZheHu            : 0.48969, 0.48974, 0.49293
        reversePairs_nomanpouigt : 0.67791, 0.68157, 0.72420
        bruteforce_loops_PM2R    : 0.82816, 0.83175, 0.83282
        bruteforce_sum_PM2R      : 1.03322, 1.03378, 1.03562
        Value: 6194
        
        Size = 320, hi = 160, 64 loops
        solutionE_TimBabych      : 0.07467, 0.07470, 0.07483
        solution_TimBabych       : 0.08036, 0.08066, 0.08077
        perm_sum_PM2R            : 0.21142, 0.21201, 0.25766
        solution_python          : 0.22410, 0.22644, 0.22897
        rank_sum_PM2R            : 0.22820, 0.22851, 0.22877
        ltree_count_PM2R         : 0.24424, 0.24595, 0.24645
        perm_radixI_PM2R         : 0.25690, 0.25710, 0.26191
        perm_radixR_PM2R         : 0.26501, 0.26504, 0.26729
        perm_fenwick_PM2R        : 0.33483, 0.33507, 0.33845
        fenwick_inline_PM2R      : 0.34413, 0.34484, 0.35153
        merge_count_BM           : 0.39875, 0.39919, 0.40302
        fenwick_PM2R             : 0.40434, 0.40439, 0.40845
        merge_PM2R               : 0.40814, 0.41531, 0.51417
        count_inversions_NiklasB : 0.41681, 0.42009, 0.42128
        count_inversion_mkso     : 0.47132, 0.47192, 0.47385
        inv_cnt_ZheHu            : 0.54468, 0.54750, 0.54893
        reversePairs_nomanpouigt : 0.76164, 0.76389, 0.80357
        bruteforce_loops_PM2R    : 1.59125, 1.60430, 1.64131
        bruteforce_sum_PM2R      : 2.03734, 2.03834, 2.03975
        Value: 24959
        
        Run 2
        
        Size = 640, hi = 320, 8 loops
        solutionE_TimBabych      : 0.04135, 0.04374, 0.04575
        ltree_count_PM2R         : 0.06738, 0.06758, 0.06874
        perm_radixI_PM2R         : 0.06928, 0.06943, 0.07019
        fenwick_inline_PM2R      : 0.07850, 0.07856, 0.08059
        perm_fenwick_PM2R        : 0.08151, 0.08162, 0.08170
        perm_sum_PM2R            : 0.09122, 0.09133, 0.09221
        rank_sum_PM2R            : 0.09549, 0.09603, 0.11270
        merge_count_BM           : 0.10733, 0.10807, 0.11032
        count_inversions_NiklasB : 0.12460, 0.19865, 0.20205
        solution_python          : 0.13514, 0.13585, 0.13814
        
        Size = 1280, hi = 640, 8 loops
        solutionE_TimBabych      : 0.04714, 0.04742, 0.04752
        perm_radixI_PM2R         : 0.15325, 0.15388, 0.15525
        solution_python          : 0.15709, 0.15715, 0.16076
        fenwick_inline_PM2R      : 0.16048, 0.16160, 0.16403
        ltree_count_PM2R         : 0.16213, 0.16238, 0.16428
        perm_fenwick_PM2R        : 0.16408, 0.16416, 0.16449
        count_inversions_NiklasB : 0.19755, 0.19833, 0.19897
        merge_count_BM           : 0.23736, 0.23793, 0.23912
        perm_sum_PM2R            : 0.32946, 0.32969, 0.33277
        rank_sum_PM2R            : 0.34637, 0.34756, 0.34858
        
        Size = 2560, hi = 1280, 8 loops
        solutionE_TimBabych      : 0.10898, 0.11005, 0.11025
        perm_radixI_PM2R         : 0.33345, 0.33352, 0.37656
        ltree_count_PM2R         : 0.34670, 0.34786, 0.34833
        perm_fenwick_PM2R        : 0.34816, 0.34879, 0.35214
        fenwick_inline_PM2R      : 0.36196, 0.36455, 0.36741
        solution_python          : 0.36498, 0.36637, 0.40887
        count_inversions_NiklasB : 0.42274, 0.42745, 0.42995
        merge_count_BM           : 0.50799, 0.50898, 0.50917
        perm_sum_PM2R            : 1.27773, 1.27897, 1.27951
        rank_sum_PM2R            : 1.29728, 1.30389, 1.30448
        
        Size = 5120, hi = 2560, 8 loops
        solutionE_TimBabych      : 0.26914, 0.26993, 0.27253
        perm_radixI_PM2R         : 0.71416, 0.71634, 0.71753
        perm_fenwick_PM2R        : 0.71976, 0.72078, 0.72078
        fenwick_inline_PM2R      : 0.72776, 0.72804, 0.73143
        ltree_count_PM2R         : 0.81972, 0.82043, 0.82290
        solution_python          : 0.83714, 0.83756, 0.83962
        count_inversions_NiklasB : 0.87282, 0.87395, 0.92087
        merge_count_BM           : 1.09496, 1.09584, 1.10207
        rank_sum_PM2R            : 5.02564, 5.06277, 5.06666
        perm_sum_PM2R            : 5.09088, 5.12999, 5.13512
        
        Size = 10240, hi = 5120, 8 loops
        solutionE_TimBabych      : 0.71556, 0.71718, 0.72201
        perm_radixI_PM2R         : 1.54785, 1.55096, 1.55515
        perm_fenwick_PM2R        : 1.55103, 1.55353, 1.59298
        fenwick_inline_PM2R      : 1.57118, 1.57240, 1.57271
        ltree_count_PM2R         : 1.76240, 1.76247, 1.80944
        count_inversions_NiklasB : 1.86543, 1.86851, 1.87208
        solution_python          : 2.01490, 2.01519, 2.06423
        merge_count_BM           : 2.35215, 2.35301, 2.40023
        rank_sum_PM2R            : 20.07048, 20.08399, 20.13200
        perm_sum_PM2R            : 20.10187, 20.12551, 20.12683
        
        Run 3
        Size = 20480, hi = 10240, 4 loops
        solutionE_TimBabych      : 1.07636, 1.08243, 1.09569
        perm_radixI_PM2R         : 1.59579, 1.60519, 1.61785
        perm_fenwick_PM2R        : 1.66885, 1.68549, 1.71109
        fenwick_inline_PM2R      : 1.72073, 1.72752, 1.77217
        ltree_count_PM2R         : 1.96900, 1.97820, 2.02578
        count_inversions_NiklasB : 2.03257, 2.05005, 2.18548
        merge_count_BM           : 2.46768, 2.47377, 2.52133
        solution_python          : 2.49833, 2.50179, 3.79819
        
        Size = 40960, hi = 20480, 4 loops
        solutionE_TimBabych      : 3.51733, 3.52008, 3.56996
        perm_radixI_PM2R         : 3.51736, 3.52365, 3.56459
        perm_fenwick_PM2R        : 3.76097, 3.80900, 3.87974
        fenwick_inline_PM2R      : 3.95099, 3.96300, 3.99748
        ltree_count_PM2R         : 4.49866, 4.54652, 5.39716
        count_inversions_NiklasB : 4.61851, 4.64303, 4.73026
        merge_count_BM           : 5.31945, 5.35378, 5.35951
        solution_python          : 6.78756, 6.82911, 6.98217
        
        Size = 81920, hi = 40960, 4 loops
        perm_radixI_PM2R         : 7.68723, 7.71986, 7.72135
        perm_fenwick_PM2R        : 8.52404, 8.53349, 8.53710
        fenwick_inline_PM2R      : 8.97082, 8.97561, 8.98347
        ltree_count_PM2R         : 10.01142, 10.01426, 10.03216
        count_inversions_NiklasB : 10.60807, 10.62424, 10.70425
        merge_count_BM           : 11.42149, 11.42342, 11.47003
        solutionE_TimBabych      : 12.83390, 12.83485, 12.89747
        solution_python          : 19.66092, 19.67067, 20.72204
        
        Size = 163840, hi = 81920, 4 loops
        perm_radixI_PM2R         : 17.14153, 17.16885, 17.22240
        perm_fenwick_PM2R        : 19.25944, 19.27844, 20.27568
        fenwick_inline_PM2R      : 19.78221, 19.80219, 19.80766
        ltree_count_PM2R         : 22.42240, 22.43259, 22.48837
        count_inversions_NiklasB : 22.97341, 23.01516, 23.98052
        merge_count_BM           : 24.42683, 24.48559, 24.51488
        solutionE_TimBabych      : 60.96006, 61.20145, 63.71835
        solution_python          : 73.75132, 73.79854, 73.95874
        
        Size = 327680, hi = 163840, 4 loops
        perm_radixI_PM2R         : 36.56715, 36.60221, 37.05071
        perm_fenwick_PM2R        : 42.21616, 42.21838, 42.26053
        fenwick_inline_PM2R      : 43.04987, 43.09075, 43.13287
        ltree_count_PM2R         : 49.87400, 50.08509, 50.69292
        count_inversions_NiklasB : 50.74591, 50.75012, 50.75551
        merge_count_BM           : 52.37284, 52.51491, 53.43003
        solutionE_TimBabych      : 373.67198, 377.03341, 377.42360
        solution_python          : 411.69178, 411.92691, 412.83856
        
        Size = 655360, hi = 327680, 4 loops
        perm_radixI_PM2R         : 78.51927, 78.66327, 79.46325
        perm_fenwick_PM2R        : 90.64711, 90.80328, 91.76126
        fenwick_inline_PM2R      : 93.32482, 93.39086, 94.28880
        count_inversions_NiklasB : 107.74393, 107.80036, 108.71443
        ltree_count_PM2R         : 109.11328, 109.23592, 110.18247
        merge_count_BM           : 111.05633, 111.07840, 112.05861
        solutionE_TimBabych      : 1830.46443, 1836.39960, 1849.53918
        solution_python          : 1911.03692, 1912.04484, 1914.69786
        
        int merge(vector<int>&nums , int low , int mid , int high){
            int size1 = mid - low +1;
            int size2= high - mid;
            vector<int>left;
            vector<int>right;
            for(int i = 0  ; i < size1 ; ++i){
                left.push_back(nums[low+i]);
            }
            for(int i = 0 ; i <size2 ; ++i){
                right.push_back(nums[mid+i+1]);
            }
            left.push_back(INT_MAX);
            right.push_back(INT_MAX);
            int i = 0 ;
            int j = 0;
            int start  = low;
            int inversion = 0 ;
            while(i < size1 && j < size2){
                if(left[i]<right[j]){
                    nums[start] = left[i];
                    start++;
                    i++;
                }else{
                    for(int l = i ; l < size1; ++l){
                        cout<<"("<<left[l]<<","<<right[j]<<")"<<endl;
                    }
                    inversion += size1 - i;
                    nums[start] = right[j];
                    start++;
                    j++;
                }
            }
            if(i == size1){
                for(int c = j ; c< size2 ; ++c){
                    nums[start] = right[c];
                    start++;
                }
            }
            if(j == size2){
                for(int c =  i ; c< size1 ; ++c){
                    nums[start] = left[c];
                    start++;
                }
            }
            return inversion;
        }
        int inversion_count(vector<int>& nums , int low , int high){
            if(high>low){
                int mid = low + (high-low)/2;
                int left = inversion_count(nums,low,mid);
                int right = inversion_count(nums,mid+1,high);
                int inversion = merge(nums,low,mid,high) + left + right;
                return inversion;
            }
            return 0 ;
        }
        
        def countInversions(arr):
         n = len(arr)
         if n == 1:
            return 0
         n1 = n // 2
         n2 = n - n1
         arr1 = arr[:n1]
         arr2 = arr[n1:]
         # print(n1,'||',n1,'||',arr1,'||',arr2)
         ans = countInversions(arr1) + countInversions(arr2)
         print(ans)
         i1 = 0
         i2 = 0
         for i in range(n):
             # print(i1,n1,i2,n2)
             if i1 < n1 and (i2 >= n2 or arr1[i1] <= arr2[i2]):
                 arr[i] = arr1[i1]
                 ans += i2
                 i1 += 1
             elif i2 < n2:
                 arr[i] = arr2[i2]
                 i2 += 1
         return ans
        
        def countInversions(arr):
              count = 0
              for i in range(len(arr)):
                  for j in range(i, len(arr)):
                       # print(arr[i:len(arr)])
                         if arr[i] > arr[j]:
                             print(arr[i], arr[j])
                             count += 1
              print(count)