题目链接:http://poj.org/problem?id=2299
思路:分治法的一个简单题目,在分支排序的过程中,对逆序对进行计数即可。例如:数组a[10], 使用分治法进行排序,不过在conquer的过程中,对左右2个有序数组中的逆序对个数进行计数(因为有序,无需每个都比较,降低了复杂度)。递归方程为 T(0,n) = T (0,n/2) + T(n/2,n) +两个有序数组的逆序对个数。
#include<iostream>
using namespace std;
int a[500001];
int n;
long long ans ;
int tmp[500001];
void divide(int a[], int s, int e){
if ( e-1 <= s )
return ;
divide(a,s,(e+s)/2);
divide(a,(e+s)/2,e);
// conquer();
int p = s;
int i=s;
int j=(e+s)/2;
while ( i != (e+s)/2 && j != e ){
if (a[i] > a[j]){
tmp[p++]=a[j++];
ans = ans + (e+s)/2-i;
}
else
tmp[p++]=a[i++];
}
while ( j != e){
tmp[p++] = a[j++];
}
while ( i != (e+s)/2){
tmp[p++] = a[i++];
}
for (int k = s; k < e ;k++){
a[k] = tmp[k];
}
}
int main(){
while (scanf("%d",&n) && n != 0){
for (int i = 0; i < n; i++)
scanf("%d",&a[i]) ;
ans = 0;
divide(a,0,n);
printf("%lld\n", ans);
}
}