逆序数 Ultra-QuickSort

参考链接:https://blog.csdn.net/wan1314mum/article/details/42561127

题目链接:https://vjudge.net/contest/243680#problem/F

Ultra-QuickSort

In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swapping two adjacent sequence elements until the sequence is sorted in ascending order. For the input sequence 

9 1 0 5 4 ,


Ultra-QuickSort produces the output 

0 1 4 5 9 .


Your task is to determine how many swap operations Ultra-QuickSort needs to perform in order to sort a given input sequence.

Input

The input contains several test cases. Every test case begins with a line that contains a single integer n < 500,000 -- the length of the input sequence. Each of the the following n lines contains a single integer 0 ≤ a[i] ≤ 999,999,999, the i-th input sequence element. Input is terminated by a sequence of length n = 0. This sequence must not be processed.

Output

For every input sequence, your program prints a single line containing an integer number op, the minimum number of swap operations necessary to sort the given input sequence.

Sample Input

5
9
1
0
5
4
3
1
2
3
0

Sample Output

6
0

根据题意,其实就是求逆序数;

思考:若是直接暴力扫描,复杂度为O(n^2),假如数据过大,会TLE,所以考虑用分治的思想,将区间一分为二考虑,那么
总区间的逆序数就为分开后的左区间里的逆序数,右区间里的逆序数和左右区间比较产生的逆序数三者之和,在左右区
间里的逆序数可以递归求得(顺便将区间排好序),而对于逆序数分别由左区间和右区间构成的数构成,我们则枚举右区
间的数,统计左区间比他大的数字,累加起来就好了。

#include<iostream>
#include<cstring>
using namespace std;

int vec[500050];
int temp[500050];

long long  ans=0;//计数尽量用long long 好几次就因为int 错了; 

void slove(int left,int mid,int right){
	int i=left;
	int j=mid;;
	int n=mid+1;
	int m=right;
	int k=0;
	while(i<=j && n<=m){
		if(vec[i]>vec[n]){
			ans+=mid-i+1;//记录左区间的数字有多少大于右边的数字; 
			temp[k++]=vec[n++];
		}
		else{
			
			temp[k++]=vec[i++];
		}
	}
	while(i<=j){
		temp[k++]=vec[i++];
	}
	while(n<=m){
		temp[k++]=vec[n++];
	}
	for(int i=0;i<k;i++){
		vec[left+i]=temp[i];
	}
}


void msort(int left,int right){
	if(left<right){
		int mid=(left+right)/2;
		msort(left,mid);
		msort(mid+1,right);
		slove(left,mid,right);
	} 
}




int main(){
	int n;
	while(cin>>n,n){ 
	ans=0;
	memset(vec,0,sizeof(vec));
	memset(temp,0,sizeof(temp));
	for(int i=0;i<n;i++){
		cin>>vec[i];
	}
	msort(0,n-1);
//	for(int i=0;i<n;i++){
//		cout<<vec[i]<<" ";
//	}
	cout<<ans<<endl;
}
	
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/guozuofeng/article/details/81389203