原题链接:107. 超快速排序
解题思路
只通过比较和交换相邻两个数值的排序方法,实际上就是冒泡排序。在排序过程中每找到一对大小颠倒的相邻数值,把他们交换,就会使整个序列的逆序对个数减少1,最终排好序后逆序对个数显然为0,所以对a进行冒泡排序的最少交换次数就是序列a种逆序对的个数。我们直接使用对并排序求出a的逆序对数就是本题的答案。
样例代码
#include <bits/stdc++.h>
using namespace std;
const int N=501000;
#define ll long long
ll n,m,i,j,k,a[N],b[N],cnt;
void merge(ll a[],ll l,ll r)
{
if (r-l<1)
return ;
ll mid=(l+r)>>1;
merge(a,l,mid);
merge(a,mid+1,r);
ll i=l,j=mid+1;
for (ll k=l;k<=r;k++)
{
if (j>r || i<=mid && a[i]<=a[j])
b[k]=a[i++];
else
{
cnt+=mid-i+1;
b[k]=a[j++];
}
}
for (ll k=l;k<=r;k++)
a[k]=b[k];
}
int main()
{
ios::sync_with_stdio(false);
while(cin>>n && n)
{
for (i=1;i<=n;i++)
cin>>a[i];
cnt=0;
merge(a,1,n);
cout<<cnt<<endl;
}
return 0;
}