51Nod-1019 逆序数

1019 逆序数 

基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题

在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序。一个排列中逆序的总数就称为这个排列的逆序数。

如2 4 3 1中,2 1,4 3,4 1,3 1是逆序,逆序数是4。给出一个整数序列,求该序列的逆序数。

Input

第1行:N,N为序列的长度(n <= 50000)
第2 - N + 1行:序列中的元素(0 <= A[i] <= 10^9)

Output

输出逆序数

Input示例

4
2
4
3
1

Output示例

4

相关问题

求逆序数,最先想到的就是归并了,归并过程中后一半数组的插入次数就是逆序总数

#include <stdio.h>
#include <string.h>
#define MAXN 50010

long long s[MAXN];
long long num[MAXN];
long long cnt;

//归并排序 
void merge( int start , int mid , int end ) {
	int i = start;
	int j = mid + 1;
	int k = start;
//  printf( "111cnt=%d\n",cnt );
	while( i<=mid && j<=end ) {
		if( num[i]<=num[j] )
			s[k++] = num[i++];
		else {
			cnt += j-k;
			s[k++] = num[j++];
		}
	}
	while( i<=mid ) {
		s[k++] = num[i++];
	}
	while( j<=end ) {
		s[k++] = num[j++];
	}
	for( i=start ; i<=end ; i++ )
		num[i] = s[i];
}

//将数组一分为2 
void mergeSort( int start , int end ) {
	if( start>=end )
		return;
//  printf( "222cnt=%d\n",cnt );
	int mid = ( start+end )/2;
	mergeSort( start,mid );
	mergeSort( mid+1,end );
	merge( start,mid,end );
}

int main() {
//  freopen( "input.txt","r",stdin );
	int n;
	while( ~scanf( "%d",&n ) ) {
		memset( num,0,sizeof(num) );
		for( int i=0 ; i<n ; i++ ) {
			scanf( "%d",&num[i] );
		}
		cnt = 0;
		mergeSort( 0,n-1 );
		printf( "%lld\n",cnt );
	}
}
扫描二维码关注公众号,回复: 2628352 查看本文章

猜你喜欢

转载自blog.csdn.net/Revenant_Di/article/details/81435167