题目链接:http://poj.org/problem?id=2299
题意:输入任意序列,求将此序列转换为递增数列后需要交换的次数。
解:通过归并排序法可以提高效率,使用冒泡肯定会超时。
注意归并时候当交换的时候ans要进行自加(m-i+1),这一步类似于求逆序数的公式。
此外要注意数的范围应该定义为__int64型。
#include<iostream> #include<cstdio> #include<ctime> #include<cstring> using namespace std; __int64 a[500005]; __int64 tem[500005]; __int64 ans; void merge(__int64 a[],__int64 tem[],int first,int last,int mid) { int i = first,j = mid+1,m = mid,n = last; int k = 0; while(i <= m && j <= n) { if(a[i] >= a[j]) { tem[k++] = a[j++]; ans += m-i+1; } else { tem[k++] = a[i++]; } } while(i <= m) { tem[k++] = a[i++]; } while(j <= n) { tem[k++] = a[j++]; } for(i = 0; i < k ;i++) { a[first+i] = tem[i]; } } void mergesort(int first,int last,__int64 a[],__int64 tem[]) { if(first < last) { int mid = (first + last)/2; mergesort(first,mid,a,tem); mergesort(mid+1,last,a,tem); merge(a,tem,first,last,mid); } } int main() { int n; while(scanf("%d",&n) && n) { ans = 0; for(int i = 0; i < n; i++) scanf("%I64d",&a[i]); memset(tem,0,sizeof(tem)); mergesort(0,n-1,a,tem); printf("%I64d\n",ans); } }