POJ 2299 Ultra-QuickSort 树状数组/归并排序 求逆序数
1.为什么最小交换次数是求数组的逆序数?
比如91054 9作为最大,它肯定要沉到最后面,所以肯定要交换4次 并且9的逆序数 (9,1)(9,0)(9,5)(9,4) 正好是4, 同时9沉下去后,其他数字的相对位置没有改变,同样的道理一个数有多少个逆序数就要交换多少次,所以肯定要交换的次数就是最小交换次数就是这些逆序数的和。
2.如何求数组逆序数?
1.归并排序时顺便记录一下逆序数的个数
void mergesort(int start,int mid,int end){
int i=start,k=start,j=mid+1;
while(i<=mid&&j<=end){
if(a[i]<=a[j])b[k++]=a[i++];
else{
ans+=j-k;//注意到如果a[i]>a[j] 此时就是找到一对逆序数,同时此时b[k]==a[i],注意到如果a[i]>a[j],那么a[i+1]>a[i]>a[j],甚至在i~j的区间内都是要大于a[j]所以要加上这些逆序数
b[k++]=a[j++];
}
}
while(i<=mid)b[k++]=a[i++];
while(j<=end)b[k++]=a[j++];
//while(start<=end)a[start++]=b[start];
for(int i=start;i<=end;i++)a[i]=b[i];
}
2.树状数组/线段树