【原】 POJ 2299 Ultra-QuickSort 逆序数 解题报告
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
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
1:
2: __int64 totalReverse = 0 ;
3:
4: void Merge(int *a,int *tmpArr,int lb,int rb,int re)
5: {
6: int le = rb-1 ;
7: int index = lb ;
8: int cpback = lb ;
9: while( lb<=le && rb<=re )
10: {
11: if( a[lb] <= a[rb] )
12: tmpArr[index++] = a[lb++] ;
13: else
14: {
15: tmpArr[index++] = a[rb++] ;
16: totalReverse += (le-lb+1) ; //*** counting the reverse-pairs
17: }
18: }
19:
20: //copy the rest to the temp array
21: while(lb<=le)
22: tmpArr[index++] = a[lb++] ;
23: while(rb<=re)
24: tmpArr[index++] = a[rb++] ;
25:
26: //copy back
27: for( ; cpback<=re ; ++cpback )
28: a[cpback] = tmpArr[cpback] ;
29: }
30:
31: void Msort(int *a,int *tmpArr,int b,int e)
32: {
33: if(b<e)
34: {
35: int mid = b+(e-b)/2 ;
36: Msort(a,tmpArr,b,mid);
37: Msort(a,tmpArr,mid+1,e);
38: Merge(a,tmpArr,b,mid+1,e);
39: }
40: }
41:
42: void MergeSort(int *a,int *tmpArr,int n)
43: {
44: Msort(a,tmpArr,0,n-1) ;
45: }
46:
47: void run2299()
48: {
49: int n ;
50: int i;
51: int *a = new int[500000];
52: int *tmpArr = new int[500000];
53: while(cin>>n)
54: {
55: if(n==0)
56: break ;
57:
58: for(i=0;i<n;++i)
59: cin>>a[i] ;
60: MergeSort(a,tmpArr,n) ;
61: cout<<totalReverse<<endl;
62: totalReverse = 0 ;
63: }
64: delete []a;
65: delete []tmpArr;
66: }