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 JAVA (judge verdict: Accepted)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;


public class Main {
	//static int [] sortedArray;

	/**
	 * @param args
	 * @throws IOException 
	 * @throws NumberFormatException 
	 */
	public static void main(String[] args) throws NumberFormatException, IOException {
		// TODO Auto-generated method stub
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int n = Integer.parseInt(br.readLine());
		//int[] inputArray = new int[n];
		Element[] inputArray = new Element[n];
		//sortedArray = new int[n];
		String[] tmpArray = br.readLine().split(" ");
		for(int i = 0; i < n; i++){
			//inputArray[i] = Integer.parseInt(tmpArray[i]);
			inputArray[i] = new Element(i, Integer.parseInt(tmpArray[i]));
			//sortedArray[i] = inputArray[i];
		}
		//Arrays.sort(inputArray);
		System.out.println( MergeSort(inputArray, 0, n));
		
//		System.out.println(inversion(inputArray));
	}
	
	static int inversion(Element[] array){
		int result = 0;
		for(int i = 0 ; i < array.length ; i++){
			if(i > array[i].id){
				result += i - array[i].id;
			}
		}
		
		return result;
	}
	
	static long Merge (Element[] array, int left, int mid, int right){
		int n1 = mid - left;
		int n2 = right - mid;
		long result = 0;
		Element[] L = new Element[n1 + 1];
		Element[] R = new Element[n2 + 1];
		
		for(int i = 0; i < n1 ; i++){
			L[i] = array[left + i];
		}
		
		for(int i = 0; i < n2 ; i++){
			R[i] = array[mid + i];
		}
		L[n1] = new Element(-1, Integer.MAX_VALUE);
		R[n2] = new Element(-1, Integer.MAX_VALUE);
		int i = 0;
		int j = 0;
		for(int k = left ; k < right ; k++){
			if(L[i].data <= R[j].data){
				array[k] = L[i];
				//System.out.print(L[i].data+" ");
				i++;
				
			}
			else {
				array[k] = R[j];
				if(n1 + j - k + left > 0 ){
					result += n1 + j - (k - left);
					//System.out.println("n1 + j:"+(n1+j)+" k - left= "+(k - left));
					//System.out.println("R["+j+"](" +R[j].data+ ") moves " +(n1 + j - (k - left)) );
					//result ++;
				}
				//System.out.println("R["+j+"]="+R[j].data);
				//System.out.print(R[j].data+" ");
				j++;
				
			}
		}
		//System.out.println();
		return result;
	}
	
	static long MergeSort (Element[] array, int left, int right){
		long result = 0;
		if(left + 1 < right){
			int mid = (left + right)/2;
			result += MergeSort(array, left, mid);
			result += MergeSort(array, mid, right);
			result += Merge(array, left, mid, right);
		}
		
		return result;
	}
	

}


class Element implements Comparable{
	int id;
	int data;
	
	public Element (int id, int data){
		this.id = id;
		this.data = data;
	}

	public int compareTo(Element data) {
		// TODO Auto-generated method stub
		if(this.data < data.data){
			return -1;
		}
		else if(this.data == data.data){
			return 0;
		}
		else {
			return 1;
		}
	}

	public int compareTo(Object arg0) {
		// TODO Auto-generated method stub
		return 0;
	}
}