poj 2299 Ultra-QuickSort

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

这题是要求数列的逆序数。所谓数列的逆序数就是一个值sum,sum=b[0]+b[1]+...+b[n-1]。这里假设数列为a,其中b[i]表示在数列中在a[i]后面并且比a[i]小的数的个数。比如有数列 2 8 0 3的逆序数就是1+2+0+0=3。
求在数列的逆序数可以使用归并排序。归并排序是将数列a[l,h]分成两半a[l,mid]和a[mid+1,h]分别进行归并排序,然后再将这两半合并起来。在合并的过程中(设l<=i<=mid,mid+1<=j<=h),当a[i]<=a[j]时,并不产生逆序数;当a[i]>a[j]时,在前半部分中比a[i]大的数都比a[j]大,将a[j]放在a[i]前面的话,逆序数要加上mid+1-i。因此,可以在归并排序中的合并过程中计算逆序数。

( ---------------------来自紫书226页 -------------------------)

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 const int M=500010;
 5 int a[M];
 6 int aux[M];
 7 long long int  ans;
 8 using namespace std;
 9 void merge(int a[],int l,int mid,int h){
10     memcpy(aux+l,a+l,sizeof(int)*(h-l+1));
11     int i=l;
12     int j=mid+1;
13     for(int k=l;k<=h;++k){
14         if(i>mid)a[k]=aux[j++];
15         else if(j>h)a[k]=aux[i++];
16         else if(aux[i]<aux[j])a[k]=aux[i++];
17         else {
18             a[k]=aux[j++];
19             ans+=mid-i+1;
20         }
21     }
22 }
23 void sort(int a[],int l,int h){
24     if(l>=h)return ;
25     int mid=l+(h-l)/2;
26     sort(a,l,mid);
27     sort(a,mid+1,h);
28     merge(a,l,mid,h);
29 }
30 int main(){
31     int n;
32     while(scanf("%d",&n)&&n!=0){
33         ans=0;
34         for(int i=0;i<n;++i)
35             scanf("%d",&a[i]);
36         sort(a,0,n-1);
37         printf("%lld
",ans);
38     }
39     return 0;
40 }
View Code

原文地址:https://www.cnblogs.com/demodemo/p/4716064.html