百练_0809:求逆序对数_归并排序

//
0809:求逆序对数
查看提交统计提问
总时间限制: 500ms 内存限制: 65536kB
描述
对于一个长度为N的整数序列A,满足i < j 且 Ai > Aj.的数对(i,j)称为整数序列A的一个逆序
请求出整数序列A的所有逆序对个数

输入
输入包含多组测试数据,每组测试数据有两行
第一行为整数N(1 <= N <= 20000),当输入0时结束
第二行为N个整数,表示长为N的整数序列
输出
每组数据对应一行,输出逆序对的个数
样例输入
5
1 2 3 4 5
5
5 4 3 2 1
1
1
0
样例输出
0
10
0


//
#include<bits/stdc++.h>
using namespace std;

const int N=1e5+6;
int a[N];
int cnt;

void merge( int *a,int *b,int x,int mid,int y )
{
    int i=x;
    int j=mid+1;
    int k=0;

    while( i<=mid && j<=y )
    {						// <= 注意逆序对的定义 
        if( a[i]<=a[j] )    b[k++]=a[i++];			// eg. 1 2 3 cnt=3-1+1
        else                b[k++]=a[j++],cnt+=mid-i+1;
    }
    while( i<=mid )         b[k++]=a[i++];
    while( j<=y )           b[k++]=a[j++];

    for( i=0;i<k;i++ )      a[x+i]=b[i];
}

void split( int *a,int *b,int x,int y )
{
    if( x<y )
    {
        int mid=( x+y )>>1;
        split( a,b,x,mid );
        split( a,b,mid+1,y );
        merge( a,b,x,mid,y );
    }
}
					// *a
bool merge_sort( int *a,int n )
{
    cnt=0;
    int *b=new int[n];
    if( b==NULL ) return false;

    split( a,b,0,n-1 );
    delete[] b;
    b=NULL;
    return true;
}

int main()
{
	int n,i;
	
    while( ~scanf("%d",&n) && n )
    {
        for( i=0;i<n;i++ ) scanf("%d",&a[i]);
        merge_sort( a,n );

        printf("%d\n",cnt);
    }
    return 0;
}
// 1 4 5 6 7 || 2 3
// 2 ~ 4 5 6 7
// 3 ~ 4 5 6 7

猜你喜欢

转载自blog.csdn.net/qq_63173957/article/details/123577042