poj 2299 Ultra-QuickSort

归并排序求逆序对数(不能理解图片乱入...)

Ultra-QuickSort

Time Limit: 7000MS Memory Limit: 65536K
Total Submissions: 36250 Accepted: 13066

Description

poj 2299 Ultra-QuickSortIn 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

Source

Waterloo local 2005.02.05

[Submit]   [Go Back]   [Status]   [Discuss]

我的解法



/*=============================================================================
#     FileName: 2299.cpp
#         Desc: poj 2299
#       Author: zhuting
#        Email: [email protected]
#     HomePage: my.oschina.net/locusxt
#      Version: 0.0.1
#    CreatTime: 2013-12-08 13:24:59
#   LastChange: 2013-12-08 13:24:59
#      History:
=============================================================================*/
/*
 * 归并排序求逆序对数
 */

#include <cstdio>
#include <cstdlib>
#include <string>
#include <cstring>
#include <algorithm>
#define maxn 500005
#define inf 1000000000
int num[maxn] = {0};
int L[maxn] = {0}, R[maxn] = {0};
long long count = 0;

void merge(int l, int mid, int r)
{
	int n1 = mid - l + 1;
	int n2 = r - mid;

	for (int i = 1; i <= n1; ++i)
		L[i] = num[l + i - 1];
	for (int i = 1; i <= n2; ++i)
		R[i] = num[mid + i];
	L[n1 + 1] = inf;
	R[n2 + 1] = inf;
	int i = 1, j = 1;
	for (int k = l; k <= r; ++k)/*合并左右区间*/
	{
		if (L[i] <= R[j])
			num[k] = L[i++];
		else/*左区间的数比右区间大时,需要计算逆序对数*/
		{
			num[k] = R[j++];
			count += (n1 - i + 1);/*只增加了这一句*/
		}
	}
	return;
}

void merge_sort(int l, int r)
{
	if (l < r)
	{
		int mid = (l + r) >> 1;
		merge_sort(l, mid);
		merge_sort(mid + 1, r);
		merge(l, mid, r);
	}
	return;
}

void init()
{
	memset(num, 0, sizeof(num));
	count = 0;
	return;
}

int main()
{
	int n = 0;
	while(scanf("%d", &n) != EOF && n)
	{
		init();
		for (int i = 1; i <= n; ++i) 
		{
			scanf("%d", &num[i]);
		}
		merge_sort(1, n);
		printf("%lld\n", count);
	}
	return 0;
}





你可能感兴趣的:(poj)