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≤109
- 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
已知逆序数等于冒泡排序的序列,但这题冒泡排序肯定超时。这题用归并排序优化一下就行。
AC代码
#include<iostream> #include<cstring> #include<stack> #include<cstdio> #include<cmath> using namespace std; #define MAX 500000 #define INF 2e9 int L[MAX/2+2],R[MAX/2+2]; long long cnt=0; long long merge(int A[],int n,int left,int mid,int right) { long long cnt=0; int n1=mid-left; int n2=right-mid; for(int i=0;i<n1;i++) { L[i]=A[left+i]; } for(int i=0;i<n2;i++) { R[i]=A[mid+i]; } L[n1]=INF; R[n2]=INF; int i=0,j=0; for(int k=left;k<right;k++)//合并 { if(L[i]<=R[j]) A[k]=L[i++]; else { A[k]=R[j++]; cnt=cnt+(n1-i); } } return cnt; } long long mergeSort(int A[],int n,int left,int right) { long long v1,v2,v3; if(left+1<right) { int mid=(left+right)/2; v1=mergeSort(A,n,left,mid); v2=mergeSort(A,n,mid,right); v3=merge(A,n,left,mid,right); return (v1+v2+v3); } else return 0; } int main() { int A[MAX],n; cnt=0; cin>>n; for(int i=0;i<n;i++) cin>>A[i]; cnt=mergeSort(A,n,0,n); cout<<cnt<<endl; return 0; }