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); } }
相关文章推荐
- POJ-----2299---Ultra-QuickSort---归并排序
- POJ 2299 Ultra-QuickSort(求逆序数)
- Ultra-QuickSort--POJ 2299
- POJ 2299 Ultra-QuickSort 【归并排序 || 树状数组求逆序对数】
- POJ 2299 Ultra-QuickSort(归并排序·树状数组·逆序对)
- poj 2299 Ultra-QuickSort 树状数组求逆序数 离散化
- POJ 2299 Ultra-QuickSort(树状数组)
- poj 2299 Ultra-QuickSort
- Poj 2299 - Ultra-QuickSort 离散化,树状数组,逆序对
- poj 2299 Ultra-QuickSort(逆序对)
- poj 2299 Ultra-QuickSort——归并排序求逆序数,线段树离散化
- poj 2299 Ultra-QuickSort(归并排序)||(树状数组+离散化)
- POJ 2299 Ultra-QuickSort(树状数组+离散化)
- poj 2299 Ultra-QuickSort(求逆序数,树状数组)
- poj 2299 Ultra-QuickSort(线段树)
- POJ 2299 Ultra-QuickSort
- POJ 2299 Ultra-QuickSort
- POJ 刷题系列:2299. Ultra-QuickSort
- poj 2299 Ultra-QuickSort(求逆序对)
- poj(2299)——Ultra-QuickSort(归并排序求逆序数)