求逆序对——Ultra-QuickSort 题解解析

Description

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
求逆序对的问题可以用冒泡排序,但是当序列够长的时候,冒泡排序的复杂度是不能满足要求的。我们可以用归并排序的思路求解。
代码如下:
 
#include <iostream>
#include <sstream>
#include <ios>
#include <iomanip>
#include <functional>
#include <algorithm>
#include <vector>
#include <string>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <climits>
#include <cctype>
using namespace std;
#define XINF INT_MAX
#define INF 0x3F3F3F3F
#define MP(X,Y) make_pair(X,Y)
#define PB(X) push_back(X)
#define REP(X,N) for(int X=0;X<N;X++)
#define REP2(X,L,R) for(int X=L;X<=R;X++)
#define DEP(X,R,L) for(int X=R;X>=L;X--)
#define CLR(A,X) memset(A,X,sizeof(A))
#define IT iterator
typedef long long ll;
typedef pair<int,int> PII;
typedef vector<PII> VII;
typedef vector<int> VI;
//const int MAXN = 10010;
//#define INF 0x3FFFFFFF
/*************************************
 **************头文件*****************
 *************************************/
ll a[500005],b[500005];
ll ans;
void Merge(ll a[],ll low,ll mid,ll high)
{
//	ll *b = new ll[high+1];///// 不能动态分配内存,会TME
	ll i = low,j = mid+1,k = low;
	while(i<=mid&&j<=high)
		if(a[i]<=a[j])
			b[k++] = a[i++];	
		else
		{
			b[k++] = a[j++];
			ans+=mid+1-i;		//这里将a[j]赋给b[k]中间跳过了mid+1-i个数
		}						//这些数就是a[j]共有多少个逆序对
	while(i<=mid)
		b[k++] = a[i++];
	while(j<=high)
		b[k++] = a[j++];
	for(i = low;i<=high;i++)
		a[i] =b[i];
}
void MergeSort(ll a[],ll n)//两路归并
{
	ll len = 1,i;
	while(len < n){
		i = 0;
		while(i+2*len<=n){
			Merge(a,i,i+len-1,i+2*len-1);
			i+=2*len;
		}
		if(i+len<n)
			Merge(a,i,i+len-1,n-1);
		len*=2;
	}
}
int main()
{
	ll n;
	while(cin>>n&&n)
	{
		REP(i,n)
			cin>>a[i];
		ans = 0;
		MergeSort(a,n);					//调用归并函数进行排序
		cout<<ans<<endl;				//直接输出答案
	} 
	return 0;
} 
 
 
 


 

你可能感兴趣的:(题解,归并排序,逆序对,Ultra-QuickSort)