逆序对的数量
【题目描述】
给定一个长度为 n 的整数数列,请你计算数列中的逆序对的数量。
逆序对的定义如下:对于数列的第 i 个和第 j 个元素,如果满足 i<j 且 a[i]>a[j],则其为一个逆序对;否则不是。
【输入格式】
第一行包含整数 n,表示数列的长度。
第二行包含 n 个整数,表示整个数列。
【输出格式】
输出一个整数,表示逆序对的个数。
【数据范围】
1≤n≤100000,
数列中的元素的取值范围 [1,109]。
【输入样例】
6
2 3 4 5 6 1
【输出样例】
5
分治策略一般分为拆分,求解,合并三个过程;本题利用归并排序过程中的合并过程。

由于归并排序合并过程中,两个待合并数组已然有序,因此可以利用这种“有序”来计算逆序对的数量。
当前半部分走到i,后半部分走到j时,假设num[i] > num[j],那么就意味着从i到mid的位置的所有数num[i~mid]都大于num[j],构成了一对逆序对,因此通过计算从i到mid共有mid - i + 1个数,即可知道当前状态下的逆序对。
1 #include <iostream> 2 using namespace std; 3 const int N = 100009; 4 int num[N],tmp[N],n; 5 long long res; 6 7 long long mergeSort(int l,int r) 8 { 9 if(l >= r) 10 return 0; 11 int mid = l + r >> 1; 12 res = mergeSort(l,mid) + mergeSort(mid + 1,r); 13 14 int i = l,j = mid + 1, k = 0; 15 while(i <= mid && j <= r) 16 { 17 if(num[i] <= num[j]) 18 tmp[k++] = num[i++]; 19 else 20 { 21 tmp[k++] = num[j++]; 22 res += mid - i + 1; 23 } 24 } 25 while(i <= mid) 26 tmp[k++] = num[i++]; 27 while(j <= r) 28 tmp[k++] = num[j++]; 29 for(int i = l,j = 0;i <= r;++i,++j) 30 num[i] = tmp[j]; 31 return res; 32 } 33 34 int main() 35 { 36 cin >> n; 37 for(int i = 0;i < n;++i) 38 cin >> num[i]; 39 cout << mergeSort(0,n-1) << endl; 40 return 0; 41 }

浙公网安备 33010602011771号