归并求逆序
模板
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

浙公网安备 33010602011771号