POJ_2299_归并排序_统计逆序数


链接: http://poj.org/problem?id=2299




分析:统计给定序列中的逆序数,蛮力法复杂度达O(n^2)会超时,由于归并排序复杂度为O(nlogn)
并且,在排序过程中可以顺便统计逆序数,所以用归并排序可以求出。


注意:在求逆序数时要注意,每当前半部分的数被加入到辅助数组中时,逆序数总数应当增加后半部分已经被添加到辅助数组中的元素的总个数.

#include<stdio.h>
#include<stdlib.h>
//归并排序统计
#define SIZE 500010 
int arr[SIZE],T[SIZE];
long long  cnt = 0;
void MergeSort(int *A,int *T,int l,int r)
{
    if(l==r)
    {
       return;
    }
    else
    {
        int mid = (l+r)/2;
        //左右递归 
        MergeSort(A,T,l,mid);
        MergeSort(A,T,mid+1,r);
        //merge
        int i,j,k;
        for(i=l,j=mid+1,k=l;k<=r;)
        {
           if(i>mid&&j<=r)
           {
              T[k++] = A[j++];
           }
           else if(i<=mid&&j<=r&&A[i]>A[j])
           {
              T[k++] = A[j++];
           }
           else if(i<=mid&&j<=r&&A[i]<=A[j])
           {
              T[k++] = A[i++];
              cnt+=(j-mid-1);
           }
           else if(i<=mid&&j>r)
           {
              cnt+=(j-mid-1);
              T[k++] = A[i++];
           }
        }
        for(int i=l;i<=r;i++)
        A[i] = T[i];
    }
}
int main()
{
    int n;
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    while(scanf("%d",&n),n)
    {
       for(int i=0;i<n;i++)
       {
          scanf("%d",&arr[i]);
       }
       cnt = 0;
       MergeSort(arr,T,0,n-1);
       printf("%I64d\n",cnt);
    }
    return 0;
}

你可能感兴趣的:(数据结构,mergesort)