归并排序

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

 

 

题目大意:

给出长度为n的序列,每次只能交换相邻的两个元素,问至少要交换几次才使得该序列为递增序列。

刚刚学了时间复杂度, 用归并排序Mergesort了,O(nlogn),省时,不会超时。

这里用归并排序并不是为了求交换次数,而是为了求序列的逆序数,而一个乱序序列的逆序数 = 在只允许相邻两个元素交换的条件下,得到有序序列的交换次数。

 

案例中的

9 1 0 5 4

要把它排列为升序0,1,4,5,9

而对于序列9 1 0 5 4

9后面却有4个比9小的元素,因此9的逆序数为4

1后面只有1个比1小的元素0,因此1的逆序数为1

0后面不存在比他小的元素,因此0的逆序数为0

5后面存在1个比他小的元素4, 因此5的逆序数为1

4是序列的最后元素,逆序数为0

因此序列9 1 0 5 4的逆序数 t=4+1+0+1+0 = 6  ,就是交换次数

(自己还不是很理解,所以拐到同学的解释来解释了........)

 

代码如下:

 

 1 #include <stdio.h>
 2 int n,A[500005],T[500005],i;
 3 long long ans=0;
 4 void merge_sort(int* A,int x,int y,int*T){
 5     if(y-x>1){
 6         int m=x+(y-x)/2;
 7         int p=x,q=m,i=x;
 8         merge_sort(A,x,m,T);
 9         merge_sort(A,m,y,T);
10         while(p<m||q<y){
11             if(q>=y||(p<m&&A[p]<=A[q])){
12                 T[i++]=A[p++];
13             }
14             else {
15                 T[i++]=A[q++];
16                 ans+=m-p;
17             }
18         }
19         for(i=x;i<y;i++) A[i]=T[i];
20     }
21 }
22 int main()
23 {
24     while(scanf("%d",&n)==1&&n){
25         ans=0;
26         for(int i=0;i<n;i++)
27             scanf("%d",&A[i]);
28         merge_sort(A,0,n,T);
29         printf("%lld\n",ans);
30     }
31     return 0;
32 }

 

 

注意:保存逆序数时,必须要用long long型定义,否则会WA的。。。 

posted @ 2015-08-03 16:15  果冻0_0  阅读(321)  评论(0编辑  收藏  举报