原题链接

考察:归并排序

思路:

         这道题的延伸 1215. 小朋友排队

        很明显就是求逆序对,借着这道题复习逆序对了

        lyd大佬的方法待补,我是真的看不懂他的算法

 1 #include <iostream>
 2 using namespace std;
 3 #define ll long long
 4 const int N = 500010;
 5 int a[N],tmp[N],n;
 6 ll merge_sort(int l,int r)
 7 {
 8     if(l>=r) return 0;
 9     int mid = l+r>>1;
10     ll cnt = merge_sort(l,mid) + merge_sort(mid+1,r);
11     int i = l; int j = mid+1; int k = 1;//在递归过程中,a数组是从l开始排序的
12     while(i<=mid&&j<=r){
13         if(a[i]<=a[j]) tmp[k++] = a[i++];
14         else{ tmp[k++] = a[j++];cnt+=(ll)mid-i+1; }
15     }
16     while(i<=mid) tmp[k++] = a[i++];
17     while(j<=r) tmp[k++] = a[j++];
18     for(int i=l,k=1;i<=r;i++,k++) a[i] = tmp[k];//k不能从l开始,因为是从1开始赋值
19     return cnt;
20 }
21 int main()
22 {
23     while(scanf("%d",&n)&&n){
24         for(int i=1;i<=n;i++) scanf("%d",&a[i]);
25         printf("%lld\n",merge_sort(1,n));
26     }
27     return 0;
28 }