/*转载请注明出处:乄心-小黄豆http://blog.csdn.net/wuxinxiaohuangdou*/
问:一串数字,经过最少多少次相邻两个数之间的交换可以得到 由小到大排序的数字串。
#include<stdio.h>
int a[500001],t[500001];
__int64 sum;
int n;
void merge(int l,int m,int r);
void merge_sort(int l,int r) //划分 与 递归
{
int m;
if(l<r) //注意条件! 一直划分到 子串为一个整数 。
{
m=(l+r)/2; //划分取中值.
merge_sort(l,m); //分为左部分 递归
merge_sort(m+1,r);//分为右部分 递归
merge(l,m,r);// 调用归并排序函数.
}
}
void merge(int l,int m,int r)
{
int p=0; //设置p指向 辅助数组空间.
int i=l,j=m+1; //设置 i,j分别指向 两个子序列串的 头 。
while(i<=m&&j<=r) //比较到一个子序列比较完了为止.
{
if(a[i]>a[j])
{
t[p++]=a[j++]; //存储最小的 放到辅助数组.
sum+=m-i+1; // 前部分的第一个数字(也就是这个子串的最小数字)大于 后部分字串的某一个数字(它)的话,前部分后面的都大于它.
}
else t[p++]=a[i++];
}
while(i<=m) t[p++]=a[i++];//把剩下的存入辅助数组.
while(j<=r) t[p++]=a[j++];
for(i=0;i<p;i++) //辅助数组 赋值回 原数组.
{
a[l+i]=t[i];
}
}
int main()
{
int i;
while(1)
{
scanf("%d",&n);
if(n==0) break;
sum=0;
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
merge_sort(0,n-1);
printf("%I64d\n",sum);
}
return 0;
}