POJ 2299 Ultra-QuickSort(归并排序)

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


你可能感兴趣的:(POJ 2299 Ultra-QuickSort(归并排序))