P3044 极端快排
时间: 1000ms / 空间: 65536KiB / Java类名: Main
描述
精灵王如此机智,得益于年轻时候的好奇心和热爱思考的习惯。
话说当年精灵王只有16岁,就思考这样的问题:
给定n个不同的整数,我们可以通过不断交换相邻的两个元素将它们升序排列呢。精灵王称之为“极端快排”。比如对于序列
9 1 0 5 4
极端快排后是
0 1 4 5 9
精灵王思考的问题是,对于给定的序列至少需要多少次两两相邻交换操作,才能完成排序。
输入格式
输入包含多组数据。对于每组数据:
第1行:整数n表示序列长度。(n
第2…n+1行:每一行包含一个整数a[i],表示数列中的一个元素。(0 ≤ a[i] ≤ 999,999,999)
输入以n = 0结束,这组数据不用处理。
输出格式
第1行:最少的两两相邻交换次数。
测试样例1
输入
5
9
1
0
5
4
3
1
2
3
0
输出
6
0
#include<stdio.h>
void merge_sort(__int64 *,__int64 ,__int64 ,__int64 *);
__int64 count;
__int64 a[2000000],t[2000000];
int main()
{
__int64 n;
while(scanf("%I64d",&n)==1&&n)
{
count=0; // 每次循环都要初始化一次
for(__int64 i=0;i<n;i++)
scanf("%I64d",&a[i]);
merge_sort(a,0,n,t);
printf("%I64d\n",count);
}
return 0;
}
void merge_sort(__int64 *a,__int64 x,__int64 y,__int64 *t)
{
if(y-x>1)
{
__int64 m=x+(y-x)/2;
merge_sort(a,x,m,t);
merge_sort(a,m,y,t);
__int64 p=x,q=m,i=x;
while(p<m||q<y)
{
if(q>=y||(p<m&&a[p]<=a[q])) t[i++]=a[p++];
else {t[i++]=a[q++];count+=m-p;} // 记录逆序对数
}
for(i=x;i<y;i++) a[i]=t[i];
}
}