题目
题解思路
可以看出题目就是求冒泡排序的交换次数 也叫逆序数。
归并排序合并是判断放不放的过程就是一个判断逆序数的过程。
待判断的点就在mid+1 (R序列中之前的以及被交换过了)和 i
所以逆序数加mid + 1 - i 即可。
AC代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
#include <map>
#include <string>
using namespace std;
const int INF = 0x3f3f3f3f;
int n ;
long long a[500100] , b[500100] ;
long long msort(int l , int r )
{
if ( l == r )
return 0 ;
int mid = l + r >> 1 ;
long long res = 0 ;
res += msort(l,mid);
res += msort(mid+1,r);
int k = l , f = mid + 1 , p = l ;
while( p <= mid && f <= r )
{
if ( a[p] > a[f] )
{
b[k] = a[f];
res += mid - p + 1 ;
f++;
k++;
}else
{
b[k] = a[p];
p++;
k++;
}
}
while (p <= mid )
{
b[k] = a[p];
p++;
k++;
}
while( f <= r )
{
b[k] = a[f];
k++;
f++;
}
for (int i = l ; i <= r ; i++ )
a[i] = b[i];
return res ;
}
int main ()
{
ios::sync_with_stdio(false);
while(cin>>n&&n)
{
for (int i = 1 ; i <= n ; i++ )
cin>>a[i];
long long ans = msort(1,n);
cout<<ans<<"\n";
}
return 0 ;
}