POJ 2299 Ultra-QuickSort

逆序数的定义: 在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序。一个排列中逆序的总数就称为这个排列的逆序数。逆序数为偶数的排列称为偶排列;逆序数为奇数的排列称为奇排列。如2431中,21,43,41,31是逆序,逆序数是4,为偶排列。 --摘自百度百科

记录数列的下标,按数列的值从小到大排序,所以后面插入的值肯定比前面的大,i - getsum(c[i].pos)就可以算出在i之前还有几个比c[i]大的数,累加就是答案

  
    
#include < stdio.h >
#include
< stdlib.h >
#include
< string .h >
struct Node{
int pos, value;
}c[
500001 ];
int a[ 500001 ], n;

int cmp( const void * a, const void * b){
Node
* n1 = (Node * )a, * n2 = (Node * )b;
return n1 -> value - n2 -> value;
}
inline
int lowbit( int t){
return t & ( - t);
}
void update( int i, int value){
while ( i <= n ){
a[i]
+= value;
i
+= lowbit(i);
}
}
int getsum( int i){
int sum = 0 ;
while ( i > 0 ){
sum
+= a[i];
i
-= lowbit(i);
}
return sum;
}
int main(){
while ( scanf( " %d " , & n) == 1 , n){
for ( int i = 1 ; i <= n; ++ i){
scanf(
" %d " , & c[i].value);
c[i].pos
= i;
}
qsort(c
+ 1 , n , sizeof (c[ 0 ]), cmp);
memset(a,
0 , sizeof (a));
__int64 ans
= 0 ; // 逆序数答案要用__int64存储..
for ( int i = 1 ; i <= n; ++ i){ // pos小 而 value大的满足逆序数定义
update(c[i].pos, 1 );
ans
+= (i - getsum(c[i].pos));
}
printf(
" %I64d\n " ,ans);
}
return 0 ;
}

你可能感兴趣的:(Quicksort)