Title: The Number of Inversions

For a given sequence A = {a0, a1, ... an-1}, the number of pairs (i, j) where ai > aj and i < j, is called the number of inversions. The number of inversions is equal to the number of swaps of Bubble Sort defined in the following program:

bubbleSort(A)
  cnt = 0 // the number of inversions
  for i = 0 to A.length-1
    for j = A.length-1 downto i+1
      if A[j] < A[j-1]
        swap(A[j], A[j-1])
        cnt++

  return cnt

For the given sequence A, print the number of inversions of A. Note that you should not use the above program, which brings Time Limit Exceeded.

Input:
In the first line, an integer n, the number of elements in A, is given. In the second line, the elements ai (i = 0, 1, .. n-1) are given separated by space characters.

Output:
Print the number of inversions in a line.

Constraints:
- 1 ≤ n ≤ 200,000
- 0 ≤ ai ≤ 10^9
- ai are all different

Sample Input 1:
5
3 5 2 1 4

Sample Output 1:
6

Sample Input 2:
3
3 1 2

Sample Output 2:
2

# Buggy version:
def merge(num, left, mid, right):
    global cnt
    inf = 10**9 + 1
    L = num[left:mid] + [inf]
    R = num[mid:right] + [inf]
    i, j = 0, 0
    for k in range(left, right):
        if L[i] <= R[j]:
            num[k] = L[i]
            i += 1
        else:
            num[k] = R[j]
            j += 1
            cnt += 1


def merge_count(num, left, right):
    if left+1 < right:
        mid = (left + right) // 2
        merge_count(num, left, mid)
        merge_count(num, mid, right)
        merge(num, left, mid, right)

cnt = 0
input()
num = list(map(int, input().split()))
merge_count(num, 0, len(num))
print(num)
print(cnt - 1)

# Fixed version:
def merge(num, left, mid, right):
    global cnt
    inf = 10**9 + 1
    L = num[left:mid] + [inf]
    R = num[mid:right] + [inf]
    i = j = 0
    for k in range(left, right):
        if L[i] <= R[j]:
            num[k] = L[i]
            i += 1
        else:
            num[k] = R[j]
            j += 1
            cnt += mid - left - i


def merge_count(num, left, right):
    if left+1 < right:
        mid = (left + right) // 2
        merge_count(num, left, mid)
        merge_count(num, mid, right)
        merge(num, left, mid, right)

cnt = 0
input()
num = list(map(int, input().split()))
merge_count(num, 0, len(num))
print(cnt)

# Buggy version:
def merge(A, left, mid, right):

    n1 = mid-left
    n2 = right-mid
    #L = [0 for i in range(n1+1)]
    #R = [0 for i in range(n2+1)]
    #for i in range(n1):
    #    L[i] = A[left+i]
    #for i in range(n2):
    #    R[i] = A[mid+i]
    L = A[left:mid]
    R = A[mid:right]
    L.append(float('inf'))
    R.append(float('inf'))
    i = 0
    j = 0
    global cnt

    for k in range(left, right):
        if L[i] <= R[j]:
            A[k] = L[i]
            i = i+1
        
        else:
            A[k] = R[j]
            j = j+1
            cnt += l-i

def mergeSort(A, left, right):
    if left+1 < right:
         mid = (left+right) // 2
         mergeSort(A, left, mid)
         mergeSort(A, mid, right)
         merge(A, left, mid, right)
    else:
        return 0

n = input()
A = list(map(int, input().split()))
cnt = 0
mergeSort(A, 0, len(A))
#print(*A)
print(str(cnt))

# Fixed version:
def merge(A, left, mid, right):

    n1 = mid-left
    n2 = right-mid
    #L = [0 for i in range(n1+1)]
    #R = [0 for i in range(n2+1)]
    #for i in range(n1):
    #    L[i] = A[left+i]
    #for i in range(n2):
    #    R[i] = A[mid+i]
    L = A[left:mid]
    l = len(L)
    R = A[mid:right]
    L.append(float('inf'))
    R.append(float('inf'))
    i = 0
    j = 0
    global cnt

    for k in range(left, right):
        if L[i] <= R[j]:
            A[k] = L[i]
            i = i+1
        
        else:
            A[k] = R[j]
            j = j+1
            cnt += l-i

def mergeSort(A, left, right):
    if left+1 < right:
         mid = (left+right) // 2
         mergeSort(A, left, mid)
         mergeSort(A, mid, right)
         merge(A, left, mid, right)
    else:
        return 0

n = input()
A = list(map(int, input().split()))
cnt = 0
mergeSort(A, 0, len(A))
#print(*A)
print(str(cnt))

# Buggy version:
def merge(A, left, mid, right):
    global count
    # count += (right - left)
    L = A[left:mid] + [int(1e9)]
    R = A[mid:right] + [int(1e9)]
    i = j = 0
    for k in range(left, right):
        if L[i] <= R[j]:
            A[k] = L[i]
            i += 1
        else:
            A[k] = R[j]
            j += 1
            count += j

def merge_sort(A, left, right):
    if left+1 < right:
        mid = (left + right) // 2
        merge_sort(A, left, mid)
        merge_sort(A, mid, right)
        merge(A, left, mid, right)

if __name__ == "__main__":
    n = int(input())
    A = list(map(int, input().strip().split()))
    count = 0
    merge_sort(A, 0, n)
    print(count)

# Fixed version:
def merge(A, left, mid, right):
    global count
    # count += (right - left)
    L = A[left:mid] + [int(1e9)]
    R = A[mid:right] + [int(1e9)]
    i = j = 0
    for k in range(left, right):
        if L[i] <= R[j]:
            A[k] = L[i]
            i += 1
        else:
            A[k] = R[j]
            j += 1
            count += (mid-left-i)

def merge_sort(A, left, right):
    if left+1 < right:
        mid = (left + right) // 2
        merge_sort(A, left, mid)
        merge_sort(A, mid, right)
        merge(A, left, mid, right)

if __name__ == "__main__":
    n = int(input())
    A = list(map(int, input().strip().split()))
    count = 0
    merge_sort(A, 0, n)
    print(count)

# Buggy version:
a = list(map(int, input().split()))

def merge_and_count(a, b):
    i, j = 0, 0
    count = 0
    m = []
    while i < len(a) and j < len(b):
        if a[i] <= b[j]:
            m.append(a[i])
            i += 1
        else:
            count += len(a)-i
            m.append(b[j])
            j += 1

    if i < len(a):
        m += a[i:]
    else:
        m += b[j:]

    return (count, m)



def sort_and_count(l):
    if len(l) == 1:
        return 0, []
    else:
        a = l[0:len(l)//2]
        b = l[len(l)//2:]
        rA, a_ = sort_and_count(a)
        rB, b_ = sort_and_count(b)
        r, l_ = merge_and_count(a, b)
#        print(a, b)
#        print(rA, rB, a_, b_, r, l_)
    return (rA+rB+r, l_)

print(sort_and_count(a)[0])

# Fixed version:
input()
a = list(map(int, input().split()))

def merge_and_count(a, b):
    i, j = 0, 0
    count = 0
    m = []
    while i < len(a) and j < len(b):
        if a[i] <= b[j]:
            m.append(a[i])
            i += 1
        else:
            count += len(a)-i
            m.append(b[j])
            j += 1

    if i < len(a):
        m += a[i:]
    else:
        m += b[j:]

    return (count, m)



def sort_and_count(l):
    if len(l) == 1:
        return 0, l
    else:
        a = l[0:len(l)//2]
        b = l[len(l)//2:]
        rA, a_ = sort_and_count(a)
        rB, b_ = sort_and_count(b)
        r, l_ = merge_and_count(a_, b_)
    return (rA+rB+r, l_)

print(sort_and_count(a)[0])

# Buggy version:
# 16D8101012J ItoJun dj Python3
count=0
def merge(A, left, mid, right):
    global count
    h=[]
    L=A[left:mid]+[2**32]
    R=A[mid:right]+[2**32]
    i=0
    j=0
    for k in range(left,right):
        if L[i] <= R[j]:
            print("{}<={}".format(L[i],R[j]))
            A[k] = L[i]
            h.append(L[i])
            i += 1
        else:
            print("{}>{}".format(L[i],R[j]))
            A[k] = R[j]
            h.append(R[j])
            j += 1
            if i < len(L)-1:
                count += len(L) - 1 - i
        
def merge_sort(A, left, right):
    if left+1 < right:
        mid=(left+right)//2
        merge_sort(A, left, mid)
        merge_sort(A, mid, right)
        merge(A, left, mid, right)

if __name__ == "__main__":
    n=int(input())
    A=list(map(int,input().split()))
    merge_sort(A,0,n)
    print(count)


# Fixed version:
# 16D8101012J ItoJun dj Python3
count=0
def merge(A, left, mid, right):
    global count
    h=[]
    L=A[left:mid]+[2**32]
    R=A[mid:right]+[2**32]
    i=0
    j=0
    for k in range(left,right):
        if L[i] <= R[j]:
            A[k] = L[i]
            h.append(L[i])
            i += 1
        else:
            A[k] = R[j]
            h.append(R[j])
            j += 1
            if i < len(L)-1:
                count += len(L) - 1 - i
        
def merge_sort(A, left, right):
    if left+1 < right:
        mid=(left+right)//2
        merge_sort(A, left, mid)
        merge_sort(A, mid, right)
        merge(A, left, mid, right)

if __name__ == "__main__":
    n=int(input())
    A=list(map(int,input().split()))
    merge_sort(A,0,n)
    print(count)

# Buggy version:
#16D8103010K Ko Okasaki
#ALDS_5_D

global cnt
cnt=0

def merge(A,left,mid,right):
    L=A[left:mid]
    R=A[mid:right]
    L.append(float("inf"))
    R.append(float("inf"))
    
    i=0
    j=0
    for k in range(left,right):
        global cnt
        if L[i]<=R[j]:
            A[k]=L[i]
            i=i+1
        else:
            A[k]=R[j]
            j=j+1
            cnt+=mid-left-i

def mergeSort(A,left,right):
    if left+1<right:
        mid=(int)((left+right)/2)
        mergeSort(A,left,mid)
        mergeSort(A,mid,right)
        merge(A,left,mid,right)

n=int(input())
S=list(map(int,input().split()))

mergeSort(S,0,n)
print(*S)
print(cnt)


# Fixed version:
#16D8103010K Ko Okasaki
#ALDS_5_D

global cnt
cnt=0

def merge(A,left,mid,right):
    L=A[left:mid]
    R=A[mid:right]
    L.append(float("inf"))
    R.append(float("inf"))
    
    i=0
    j=0
    for k in range(left,right):
        global cnt
        if L[i]<=R[j]:
            A[k]=L[i]
            i=i+1
        else:
            A[k]=R[j]
            j=j+1
            cnt+=mid-left-i

def mergeSort(A,left,right):
    if left+1<right:
        mid=(int)((left+right)/2)
        mergeSort(A,left,mid)
        mergeSort(A,mid,right)
        merge(A,left,mid,right)

n=int(input())
S=list(map(int,input().split()))

mergeSort(S,0,n)
print(cnt)

# Buggy version:
global cnt
cnt=0

def merge(A,left,mid,right):
    L=A[left:mid]
    R=A[mid:right]
    L.append(float("inf"))
    R.append(float("inf"))
    
    i=0
    j=0
    for k in range(left,right):
        global cnt
        if L[i]<=R[j]:
            A[k]=L[i]
            i=i+1
        else:
            A[k]=R[j]
            j=j+1
            cnt+=mid-left-i

def mergeSort(A,left,right):
    if left+1<right:
        mid=(int)((left+right)/2)
        mergeSort(A,left,mid)
        mergeSort(A,mid,right)
        merge(A,left,mid,right)

n=int(input())
S=list(map(int,input().split()))

mergeSort(S,0,n)
print(*S)
print(cnt)


# Fixed version:
global cnt
cnt=0

def merge(A,left,mid,right):
    L=A[left:mid]
    R=A[mid:right]
    L.append(float("inf"))
    R.append(float("inf"))
    
    i=0
    j=0
    for k in range(left,right):
        global cnt
        if L[i]<=R[j]:
            A[k]=L[i]
            i=i+1
        else:
            A[k]=R[j]
            j=j+1
            cnt+=mid-left-i

def mergeSort(A,left,right):
    if left+1<right:
        mid=(int)((left+right)/2)
        mergeSort(A,left,mid)
        mergeSort(A,mid,right)
        merge(A,left,mid,right)

n=int(input())
S=list(map(int,input().split()))

mergeSort(S,0,n)
print(cnt)

# Buggy version:
cnt = 0
def merge(A,left,mid,right):
    global cnt
    n1 = mid - left
    n2 = right - mid

    L = [A[i] for i in range(left, mid)]
    R = [A[i] for i in range(mid, right)]
    L.append(float("inf"))
    R.append(float("inf"))
    i = 0
    j = 0
    for k in range(left, right):
        if L[i] <= R[j]:
            A[k] = L[i]
            i += 1
        else:
            cnt += n1 - i
            A[k] = R[j]
            j += 1

def mergeSort(A,left,right):
        if left + 1 < right:
            mid = (left+right) // 2
            mergeSort(A,left,mid)
            mergeSort(A,mid,right)
            merge(A,left,mid,right)

input()
a = list(map(int, input().split()))
mergeSort(a, 0, len(a))
return cnt



# Fixed version:
cnt = 0
def merge(A,left,mid,right):
    global cnt
    n1 = mid - left
    n2 = right - mid

    L = [A[i] for i in range(left, mid)]
    R = [A[i] for i in range(mid, right)]
    L.append(float("inf"))
    R.append(float("inf"))
    i = 0
    j = 0
    for k in range(left, right):
        if L[i] <= R[j]:
            A[k] = L[i]
            i += 1
        else:
            cnt += n1 - i
            A[k] = R[j]
            j += 1

def mergeSort(A,left,right):
        if left + 1 < right:
            mid = (left+right) // 2
            mergeSort(A,left,mid)
            mergeSort(A,mid,right)
            merge(A,left,mid,right)

input()
a = list(map(int, input().split()))
mergeSort(a, 0, len(a))
print(cnt)

# Buggy version:
def merge(a, left, mid, right):
    INF = int(1e+11)
    l = a[left:mid]
    r = a[mid:right]
    l.append(INF)
    r.append(INF)
    i = 0
    j = 0

    ans = 0

    for k in range(left, right):
        if l[i] <= r[j]:
            a[k] = l[i]
            i += 1
        else:
            a[k] = r[j]
            j += 1
            if l[i] != INF:
                ans += 1

    return ans


def merge_sort(a, left, right):
    ans = 0
    if left + 1 < right:
        mid = (left + right) // 2
        ans += merge_sort(a, left, mid)
        ans += merge_sort(a, mid, right)
        ans += merge(a, left, mid, right)
    return ans

n = int(input())
a = [int(x) for x in input().split()]

print(merge_sort(a, 0, len(a)))


# Fixed version:
def merge(a, left, mid, right):
    INF = int(1e+11)
    l = a[left:mid]
    r = a[mid:right]
    l.append(INF)
    r.append(INF)
    i = 0
    j = 0

    ans = 0

    for k in range(left, right):
        if l[i] <= r[j]:
            a[k] = l[i]
            i += 1
        else:
            a[k] = r[j]
            j += 1
            if l[i] != INF:
                ans += mid - left - i

    return ans


def merge_sort(a, left, right):
    ans = 0
    if left + 1 < right:
        mid = (left + right) // 2
        ans += merge_sort(a, left, mid)
        ans += merge_sort(a, mid, right)
        ans += merge(a, left, mid, right)
        # print(left, right, ans)
    return ans

n = int(input())
a = [int(x) for x in input().split()]

print(merge_sort(a, 0, len(a)))

# Buggy version:
INF = float("inf")
cnt = 0
def merge(A, left, mid, right):
    global cnt
    L = A[left: mid] + [INF]
    R = A[mid: right] + [INF]
    i = j = 0
    for k in range(left, right):
        if L[i] <= R[j]:
            A[k] = L[i]
            cnt += j
            i += 1
        else:
            A[k] = R[j]
            j += 1
def mergeSort(A, left, right):
    if left + 1 < right:
        mid = (left + right) // 2
        mergeSort(A, left, mid)
        mergeSort(A, mid, right)
        merge(A, left, mid, right)
n = int(input())
S = list(map(int, input().split()))
mergeSort(S, 0, n)
print(*S)
print(cnt)



# Fixed version:
def merge(A,left,mid,right):
    L=A[left:mid]+[float("INF")]
    R=A[mid:right+1]+[float("INF")]
    i=0
    j=0
    global cnt
    for k in range(left,right+1):
        if L[i]<=R[j]:
            A[k]=L[i]
            i+=1
        else:
            A[k]=R[j]
            j+=1
            cnt+=len(L)-i-1
def mergeSort(A,left,right):
    if left<right:
        mid=(left+right)//2+1
        mergeSort(A,left,mid-1)
        mergeSort(A,mid,right)
        merge(A,left,mid,right)
n=int(input())
S=list(map(int,input().split()))
cnt=0
mergeSort(S,0,n-1)
print(cnt)