题目链接: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;
}