//
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