Description
![](http://poj.org/images/2299_1.jpg)
Ultra-QuickSort produces the output
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
求逆序对数,具体思路是,在归并的过程中计算每个小区间的逆序对数,进而计算出大区间的逆序对数.
归并过程为:比较a[i]和a[j]的大小,若a[i]≤a[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1;否则将第二个有序表中的元素a[j]复制到r[k]中,并令j和k分别加上1,如此循环下去,直到其中一个有序表取完,然后再将另一个有序表中剩余的元素复制到r中从下标k到下标t的单元。归并排序的算法我们通常用递归实现,先把待排序区间[s,t]以中点二分,接着把左边子区间排序,再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的区间[s,t]。
归并实现:直接套模板
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 int n,a[500005],b[500005]; 5 long long count; 6 void Merge(int *a,int left,int mid,int right) 7 { 8 int i=left,j=mid+1,k=left; 9 while(i!=mid+1&&j!=right+1) 10 { 11 if(a[i]>a[j]) 12 { 13 //count+=j-k; 14 b[k++]=a[j++]; 15 count+=mid-i+1; 16 } 17 else 18 { 19 b[k++]=a[i++]; 20 } 21 } 22 while(i!=mid+1) 23 b[k++]=a[i++]; 24 while(j!=right+1) 25 b[k++]=a[j++]; 26 for(i=left; i<=right; i++) 27 a[i]=b[i]; 28 } 29 void Merge_sort(int *a,int left,int right) 30 { 31 if(left==right) 32 return ; 33 int mid=(left+right)>>1; 34 Merge_sort(a,left,mid); 35 Merge_sort(a,mid+1,right); 36 Merge(a,left,mid,right); 37 } 38 int main() 39 { 40 while(scanf("%d",&n),n) 41 { 42 count=0; 43 for(int i=0; i<n; i++) 44 scanf("%d",&a[i]); 45 Merge_sort(a,0,n-1); 46 printf("%lld ",count); 47 } 48 return 0; 49 }