1 /* 2 题意让你求交换次序,实际求逆序对数即可 3 而归并排序时,刚好需要比较mid两边的数,所以只需在归并时累加即可 4 5 例:(归并时一定会排好小组内的顺序) 6 7 对应位置: i m j 8 对应数字: 4 5 6 1 2 3 9 10 4 > 1 -> ans += 3;//因为4为前半最小值,则前半部分所有元素符合要求(ans += m-i+1) 11 4 > 2 -> ans += 3; 12 4 > 3 -> ans += 3; 13 */ 14 #include <iostream> 15 using namespace std; 16 const int maxn = 500010; 17 int a[maxn],t[maxn]; 18 long long ans; 19 void merge(int a[], int l, int m, int r) 20 int i = l, j = m + 1, x = m, y = r, k = 0; 21 while(i <= x && j <= y) 22 if(a[i] > a[j])//记录答案 23 { 24 t[k++] = a[j++]; 25 ans += x-i+1; 26 } 27 else t[k++] = a[i++]; 28 while(i <= x) t[k++] = a[i++]; 29 while(j <= y) t[k++] = a[j++]; 30 for(int i = 0; i < k; ++i) 31 a[l+i] = t[i]; 32 } 33 void merge_sort(int a[],int l,int r) 34 { 35 if(l >= r) return; 36 int m = (l+r)/2; 37 merge_sort(a,l,m); 38 merge_sort(a,m+1,r); 39 merge(a,l,m,r); 40 } 41 int main() 42 { 43 int n; 44 while(cin >> n && n) 45 { 46 ans = 0; 47 for(int i = 0; i < n; ++i) 48 cin >> a[i]; 49 merge_sort(a,0,n-1); 50 cout << ans << endl; 51 } 52 return 0; 53 }