【原】 POJ 2299 Ultra-QuickSort 逆序数 解题报告
2010-11-05 19:22
501 查看
http://poj.org/problem?id=2299
方法:
利用merge sort求逆序数,复杂度nlgn
如果比较每一对儿数(或使用bubble sort),复杂度为n^2,太慢
对于一对儿逆序对儿,有三种情况:两数都在数组左半边,两数都在数组右半边,两数分别在左右两个半边。
由于Merge时两个半边都为sorted,所以只会出现第三种情况。
计算逆序数只需要在Merge中加一句即可,当a[lb]>a[rb]时,a[lb...le]>a[rb],所以逆序数为(le-lb+1)
由于题目中n<500,000,所以逆序数为O(n^2),需要使用__int64存放,不然会溢出
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
![](http://images.cnblogs.com/cnblogs_com/allensun/Windows-Live-Writer/-POJ-2299-Goldbachs-Conjecture--_10FD8/clip_image001_thumb.jpg)
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
[code] [code]
__int64 totalReverse = 0 ;
void Merge(int *a,int *tmpArr,int lb,int rb,int re)
{
int le = rb-1 ;
int index = lb ;
int cpback = lb ;
while( lb<=le && rb<=re )
{
if( a[lb] <= a[rb] )
tmpArr[index++] = a[lb++] ;
else
{
tmpArr[index++] = a[rb++] ;
totalReverse += (le-lb+1) ; //*** counting the reverse-pairs
}
}
//copy the rest to the temp array
while(lb<=le)
tmpArr[index++] = a[lb++] ;
while(rb<=re)
tmpArr[index++] = a[rb++] ;
//copy back
for( ; cpback<=re ; ++cpback )
a[cpback] = tmpArr[cpback] ;
}
void Msort(int *a,int *tmpArr,int b,int e)
{
if(b<e)
{
int mid = b+(e-b)/2 ;
Msort(a,tmpArr,b,mid);
Msort(a,tmpArr,mid+1,e);
Merge(a,tmpArr,b,mid+1,e);
}
}
void MergeSort(int *a,int *tmpArr,int n)
{
Msort(a,tmpArr,0,n-1) ;
}
void run2299()
{
int n ;
int i;
int *a = new int[500000];
int *tmpArr = new int[500000];
while(cin>>n)
{
if(n==0)
break ;
for(i=0;i<n;++i)
cin>>a[i] ;
MergeSort(a,tmpArr,n) ;
cout<<totalReverse<<endl;
totalReverse = 0 ;
}
delete []a;
delete []tmpArr;
}
[/code]
[/code]
相关文章推荐
- Pku acm 2299 Ultra-QuickSort 排序算法解题报告(四)----归并排序(MegerSort)求逆序数
- POJ - 2299 Ultra-QuickSort解题报告
- poj 2299 Ultra-QuickSort(树状数组求逆序数+离散化)
- poj2299 Ultra-QuickSort(树状数组求逆序数,离散化)
- POJ 2299 Ultra-QuickSort——离散化+线段树求逆序数
- poj 2299 Ultra-QuickSort 线段树求逆序数+离散化||归并排序求逆序数
- POJ 2299 Ultra-QuickSort 【树状数组 离散化 逆序对】
- poj 2299 Ultra-QuickSort (离散化,树状数组,逆序对)
- POJ 2299 Ultra-QuickSort 【归并排序求逆序数 OR 树状数组求逆序数】
- (POJ 2299)Ultra-QuickSort 树状数组求逆序对数 + 离散化
- POJ 2299 Ultra-QuickSort(逆序对数,线段树/树状数组/归并排序)
- POJ2299 Ultra-QuickSort【树状数组】【逆序数】
- poj 2299 归并排序求逆序对 解题报告
- poj 2299 Ultra-QuickSort 求逆序数,树状数组解法,详细解析
- POJ - 2299 Ultra-QuickSort —— 逆序对
- [普及] 求序列中逆序对的个数 [poj 2299 Ultra-QuickSort]
- poj2299 Ultra-QuickSort--求逆序对+树状数组
- poj 2299 Ultra-QuickSort :归并排序求逆序数
- POJ 2299 Ultra-QuickSort【树状数组 ,逆序数】
- POJ_2299_Ultra-QuickSort & NYOJ_117_求逆序数