POJ 2299 Ultra-QuickSort 树状数组/归并排序 求逆序数

1.为什么最小交换次数是求数组的逆序数?

比如91054    9作为最大,它肯定要沉到最后面,所以肯定要交换4次 并且9的逆序数 (9,1)(9,0)(9,5)(9,4) 正好是4, 同时9沉下去后,其他数字的相对位置没有改变,同样的道理一个数有多少个逆序数就要交换多少次,所以肯定要交换的次数就是最小交换次数就是这些逆序数的和。

2.如何求数组逆序数?

1.归并排序时顺便记录一下逆序数的个数 

void mergesort(int start,int mid,int end){
    int i=start,k=start,j=mid+1;
    while(i<=mid&&j<=end){
        if(a[i]<=a[j])b[k++]=a[i++];
        else{
            ans+=j-k;//注意到如果a[i]>a[j] 此时就是找到一对逆序数,同时此时b[k]==a[i],注意到如果a[i]>a[j],那么a[i+1]>a[i]>a[j],甚至在i~j的区间内都是要大于a[j]所以要加上这些逆序数
            b[k++]=a[j++];
        }
    }
        while(i<=mid)b[k++]=a[i++];
        while(j<=end)b[k++]=a[j++];
        //while(start<=end)a[start++]=b[start];    
        for(int i=start;i<=end;i++)a[i]=b[i];
} 

2.树状数组/线段树

http://blog.csdn.net/lirui7610/article/details/79586404

posted @ 2018-03-18 16:27  LandingGuys  阅读(90)  评论(0编辑  收藏  举报