Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

The Number of Inversions

For a given sequence $A = \{a_0, a_1, ... a_{n-1}\}$, the number of pairs $(i, j)$ where $a_i > a_j$ 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 $a_i$ ($i = 0, 1, .. n-1$) are given separated by space characters.

output

Print the number of inversions in a line.

Constraints

$ 1 \leq n \leq 200,000$

$ 0 \leq a_i \leq 10^9$

$a_i$ 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

Solution in C# (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PGC
{
	class Program
	{
		static void Main(string[] args)
		{
			var N = int.Parse(Console.ReadLine());
			var A = Console.ReadLine().Split().Select(int.Parse).ToArray();
			var B = new int[N];

			var count = MergeSort(A, B, 0, N);
			System.Console.WriteLine(count);
		}

		static long MergeSort(int[] array, int[] work, int left, int right)
		{
			var n = right - left;
			var mid = (left + right) / 2;
			if (n <= 1)
			{
				return 0;
			}
			var c = 0L;
			c += MergeSort(array, work, left, mid);
			c += MergeSort(array, work, mid, right);
			c += Merge(array, work, left, right);
			return c;
		}

		static long Merge(int[] array, int[] work, int left, int right)
		{
			var n = right - left;
			var mid = (left + right) / 2;
			var li = 0;
			var ri = 0;
			var c = 0L;
			for (int i = 0; i < n; i++)
			{
				var lv = left + li < mid ? array[left + li] : int.MaxValue;
				var rv = mid + ri < right ? array[mid + ri] : int.MaxValue;
				if (lv < rv)
				{
					work[left + i] = lv;
					li++;
				}
				else
				{
					work[left + i] = rv;
					ri++;
					c += n / 2 - li;
				}
			}

			for (int i = 0; i < n; i++)
			{
				array[left + i] = work[left + i];
			}

			return c;
		}
	}
}