概述
Ultra-QuickSort
Time Limit: 7000MS Memory Limit: 65536K
Total Submissions: 50482 Accepted: 18516
Description
In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swapping two adjacent sequence elements until the sequence is sorted in ascending order. For the input sequence
9 1 0 5 4 ,
Ultra-QuickSort produces the output
0 1 4 5 9 .
Your task is to determine how many swap operations Ultra-QuickSort needs to perform in order to sort a given input sequence.
Input
The input contains several test cases. Every test case begins with a line that contains a single integer n < 500,000 – the length of the input sequence. Each of the the following n lines contains a single integer 0 ≤ a[i] ≤ 999,999,999, the i-th input sequence element. Input is terminated by a sequence of length n = 0. This sequence must not be processed.
Output
For every input sequence, your program prints a single line containing an integer number op, the minimum number of swap operations necessary to sort the given input sequence.
Sample Input
5
9
1
0
5
4
3
1
2
3
0
Sample Output
6
0
题意:
求一个序列的逆序对数。
题解:
这题是可以用分治做的。我们考虑把一个序列分成两部分。那这个序列的逆序对数就等与每一部分的逆序对数加上合并的逆序对数,比如我们在s1(2,3,5)和s2(1,4)两个序列,当拿1时,可以知道它和s1里的三个数组合的都是逆序对。接着拿2,3.当拿到4时,4和5是逆序,如此一来,如果s1和s2是有序的。那么在归并排序合并时就能直接算出来有多少对逆序数。时间复杂度就是归并排序的时间复杂度,时间上界为O(nlogn)
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#define SIZE 500000
#define f(i,a,b) for(int i = a;i<=b;i++)
#define fi(i,a,b) for(int i = a;i>=b;i--)
using namespace std;
int a[SIZE];
int b[SIZE];
long long Merge(int low,int mid,int high){
long long sum = 0;
int s = low,t = mid + 1,k = low;
while(s<=mid&&t<=high){
if(a[s]<a[t]){
b[k] = a[s++];
}else{
sum+=mid-low+1-(s-low);
b[k] = a[t++];
}
k++;
}
if(s == mid+1) f(i,k,high) b[i] = a[t++];
else f(i,k,high) b[i] = a[s++];
f(i,low,high) a[i] = b[i];
return sum;
}
long long MergeSort(int low,int high){
if(low<high){
int mid = (low+high)/2;
long long k1 = MergeSort(low,mid);
long long k2 = MergeSort(mid+1,high);
long long k3 = Merge(low,mid,high);
return k1+k2+k3;
}
else
return 0;
}
int main()
{
int n;
while(scanf("%d",&n)&&n){
f(i,1,n) scanf("%d",&a[i]);
printf("%lldn",MergeSort(1,n));
}
return 0;
}
最后
以上就是彩色季节为你收集整理的POJ 2299 分治法求数列逆序对(归并排序)的全部内容,希望文章能够帮你解决POJ 2299 分治法求数列逆序对(归并排序)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复