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;
}

posted @ 2011-04-17 14:29  L..  阅读(176)  评论(0编辑  收藏  举报