归并求逆序

模板

 1 #include <iostream>
 2 #include <cstdio>
 3 using namespace std;
 4 
 5 #define maxn 500010
 6 int n, num;
 7 
 8 //要归并的序列
 9 int seq[maxn];
10 //暂存序列
11 int str[maxn];
12 //逆序数
13 long long count;
14 
15 //归并排序的子排序,将2个穿归并成一个,求逆序数
16 template<typename T>
17 long long mergeCountNum(T str1, int size1, T str2, int size2)
18 {
19     int i,j,k;
20     long long num;
21     i = j = k = num = 0;
22 
23     //取2个串中较小元,组成总串
24     while(i < size1 && j < size2){
25         if(str1[i] <= str2[j]){
26             str[k++] = str1[i++];
27             //加上逆序数
28             num += j;
29         }
30         else str[k++] = str2[j++];
31     }
32 
33     //将剩余的元素合并到总串后
34     while (i < size1){
35         str[k++] = str1[i++];
36         //加上逆序数
37         num += j;
38     }
39     while (j < size2)
40         str[k++] = str2[j++];
41 
42     //拷贝总串
43     for (int x = 0; x < (size1 + size2); x++)
44         str1[x] = str[x];
45 
46     return num;
47 }
48 
49 //分治归并排序并返回逆序数
50 template<typename T>
51 long long mergesort(T str, int size)
52 {
53     if(size <= 1) return 0;
54     T str1 = str;
55     int size1 = size / 2;
56     T str2 = str + size1;
57     int size2 = size - size1;
58     return mergesort(str1,size1) + mergesort(str2,size2)
59         + mergeCountNum(str1,size1,str2,size2);
60 }
61 
62 int main()
63 {
64     while(scanf("%d", &n), n){
65         for(int i = 0; i < n; i++){
66             scanf("%d", seq+i);
67         }
68         count = mergesort(seq, n);
69         printf("%lld\n", count);
70     }
71     return 0;
72 }
73 
74 //POJ2299

 

posted @ 2016-02-21 15:58  喷水小火龙  阅读(106)  评论(0)    收藏  举报