题目链接:Ultra-QuickSort
解题思路:之前一直没有自己动手写过归并排序,这个题目数据量很大归并排序平均复杂度为nlogn,又可以利用来求逆序数。这个题就是求逆序数(线性代数中有写)。就是当两个排好序的数组归并的时候如果去的数字是右面数组的,那么这是要在逆序数上面加上左面数组剩余数字的个数。最后逆序数要用__int64来表示。注意是%I64d。
#include<stdio.h> #include<string.h> #include<malloc.h> #define MAX 500010 __int64 ans; __int64 number[MAX], tem[MAX]; void Merge(int left, int mid, int right){ int tems = left; int i = left; int smid = mid - 1; for(; left <= smid && mid <= right; tems++){ if(number[left] <= number[mid]){ tem[tems] = number[left++]; } else{ tem[tems] = number[mid++]; ans += smid + 1 - left; } } for(; left <= smid; tems++, left++){ tem[tems] = number[left]; } for(; mid <= right; tems++, mid++){ tem[tems] = number[mid]; } for(; i <= right; i++){ number[i] = tem[i]; } } void mergesort(int left, int right){ if(left < right){ int mid = (left + right) >> 1; mergesort(mid + 1, right); mergesort(left, mid); Merge(left, mid + 1, right); } } int main(){ int n, i; while(scanf("%d", &n) && n){ ans = 0; for(i = 0; i < n; i++){ scanf("%I64d", &number[i]); } mergesort(0, n - 1); printf("%I64d\n", ans); } return 0; }