您的位置:首页 > 产品设计 > UI/UE

poj 2299 Ultra-QuickSort

2011-08-06 13:08 330 查看


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

http://poj.org/problem?id=2299

这是一道并归排序求逆序数的问题~

有一点需要注意~a[i]的范围是 n < 500,000~当情况最坏时~

逆序数count就会为124999750000~需要用long long 表示~否则就会WA~

这道题据说还可以用树状数组做~时间更短~

用并归排序有两种方式~只有小小区别~

方法一~

#include"cstdio"
long long count;
int a[500010];
void Merge(int arry[500010],int p,int q,int r)
{
int begin1=p;
int end1=q;
int begin2=q+1;
int end2=r;
int temp[500010];
int k=0;
int i;
while((begin1<=end1)&&(begin2<=end2))
{
if(arry[begin1]>arry[begin2])
{
temp[k++]=arry[begin2++];
count+=q-begin1+1;
}
else
temp[k++]=arry[begin1++];
}
while(begin1<=end1)
{
temp[k++]=arry[begin1];
begin1++;
}
while(begin2<=end2)
{
temp[k++]=arry[begin2];
begin2++;
}
for(i=p;i<=r;i++)
a[i]=temp[i-p];
}
void MSort(int arry[500010],int begin,int end)
{
int mid;
if(begin<end)
{
mid=(begin+end)/2;
MSort(arry,begin,mid);
MSort(arry,mid+1,end);
Merge(arry,begin,mid,end);
}
}

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

方法二~

#include"cstdio"
long long count;
int a[500010];
void Merge(int arry[500010],int p,int q,int r)
{
int begin1=p;
int end1=q;
int begin2=q+1;
int end2=r;
int temp[500010];
int k=0;
int i;
while((begin1<=end1)&&(begin2<=end2))
{
if(arry[begin1]<arry[begin2])
{
temp[k++]=arry[begin1++];
count+=begin2-(q+1);
}
else
temp[k++]=arry[begin2++];
}
while(begin1<=end1)
{
temp[k++]=arry[begin1];
begin1++;
count+=end2-q;
}
while(begin2<=end2)
{
temp[k++]=arry[begin2];
begin2++;
}
for(i=p;i<=r;i++)
a[i]=temp[i-p];
}
void MSort(int arry[500010],int begin,int end)
{
int mid;
if(begin<end)
{
mid=(begin+end)/2;
MSort(arry,begin,mid);
MSort(arry,mid+1,end);
Merge(arry,begin,mid,end);
}
}

int main()
{
int i;
int n;
scanf("%d",&n);
while(n)
{
count=0;
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
MSort(a,1,n);
printf("%lld\n",count);
scanf("%d",&n);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息