逆序对 分治nlogn

定义:A是包含n个元素的有序序列{a1,a2 … an},若ai > aj 且 i < j ,则称 (ai , aj)是A的一个逆序对。求逆序对是指求出A中存在逆序对的数量。

这个算法是归并排序的演化,仅需加上一行,就可以求逆序对个数。

简单的概括是:在把两个子序列合并时(两个子序列已经有序),如果当前选的最小的数在后面那个序列中,就把ans加上前面那个数组剩下的元素个数。  

具体一点来讲,设指针i,j分别指向左子序列和右子序列中的某个数,即low<=I<=mid,mid+1<=J<=high。当i<j,如果a[i]>a[j],即a[i]和a[j]为一个逆序对,因为两个子串都是由小到大排好序的,可知a[l]…a[mid]均大于a[j],均可以构成逆序对,共有mid-l+1个。

void he(int st,int end,int mid){
    int l=st,r=mid+1;
    for(int i=st;i<=end;i++){
        if(l<=mid&&(r>end||a[l]<=a[r])){
            temp[i]=f[l]; l++;
        }
        else{
            temp[i]=a[r]; r++;
            ans+=mid-l+1;
        }
    }
    for(int i=st;i<=end;i++)a[i]=temp[i];
}
void my_msort(int l,int r){
    if(l<r){
        int mid=(l+r)/2;
        my_msort(l,mid);
        my_msort(mid+1,r);
        he(l,r,mid);
    }
}

最后ans即是逆序对个数

 

posted @ 2016-07-08 12:12  FuTaimeng  阅读(713)  评论(1编辑  收藏  举报