POJ - 2299 Ultr-QuickSort

Ultra-QuickSort

Time Limit: 7000MS Memory Limit: 65536K
Total Submissions: 74536 Accepted: 27900
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
Source

Waterloo local 2005.02.05

归并排序。或者说现在意识到和线段树有点像。
直接上代码

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<cstring>
#define ll long long
using namespace std;

int a[500000] = {},c[500000] = {};
ll sum = 0;

void rs(int l,int r)
{
	if (l >= r) return;
	int mid = (l + r) / 2;
	rs(l,mid);//查询左区间 
	rs(mid+1,r);//查询右区间 
	int i = l,j = mid+1,len = 0;//开始合并 
	while (i <= mid && j <= r)
	{
		if (a[j] < a[i])//如果右区间里存在比左区间小的数,则逆序数加上左区间剩余的数的个数 
		{
			c[++len] = a[j];
			sum += (ll)mid - (ll)i + 1;
			j++;
		}
		else
		{
			c[++len] = a[i];
			i++;
		}
	}
	if (i <= mid)
	{
		while (i <= mid)//如果左区间里还有剩余的 
		{
			c[++len] = a[i];
			i++;
		}
	}
	else if (j <= r)
	{
		while (j <= r)//如果右区间里还有剩余的 
		{
			c[++len] = a[j];
			j++;
		}
	}
	int k = 0;
	for (int i = l;i<=r;i++)//合并覆盖原来的顺序 
	{
		a[i] = c[++k];
		c[k] = 0;
	}
} 

int main()
{
	int n;
	while (scanf("%d",&n) && n != 0)
	{
		memset(a,0,sizeof(a));
		for (int i = 1;i<=n;i++) scanf("%d",&a[i]);
		sum = 0;
		rs(1,n);
		printf("%lld\n",sum);
	}
}

蒟蒻的线段树学习orz…

var code = “b9bb9d59-1838-4e19-9d65-91f408237d68”

posted @ 2019-03-25 19:54  Un-Defined  阅读(4)  评论(0编辑  收藏  举报  来源