poj 2299 Ultra-QuickSort
2011-05-04 02:20
316 查看
逆序数的定义: 在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序。一个排列中逆序
的总数就称为这个排列的逆序数。逆序数为偶数的排列称为偶排列;逆序数为奇数的排列称为奇排列。如2431中,21,43,41,31是逆序,
逆序数是4,为偶排列。 --摘自百度百科
记录数列的下标,按数列的值从小到大排序,所以后面插入的值肯定比前面的大,i - getsum(c[i].pos)就可以算出在i之前还有几个比c[i]大的数,累加就是答案
的总数就称为这个排列的逆序数。逆序数为偶数的排列称为偶排列;逆序数为奇数的排列称为奇排列。如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; }
相关文章推荐
- 【原】 POJ 2299 Ultra-QuickSort 逆序数 解题报告
- POJ 2299 Ultra-QuickSort (树状数组 + 离散化)
- poj 2299 Ultra-QuickSort
- POJ 2299 Ultra-QuickSort (求逆序数:离散化+树状数组或者归并排序求逆序数)
- poj 2299 Ultra-QuickSort 【线段树求和(点更新)】
- POJ训练计划2299_Ultra-QuickSort(线段树/单点更新)
- poj 2299 Ultra-QuickSort【归并排序求逆序数】
- POJ 2299 Ultra-QuickSort
- poj 2299 Ultra-QuickSort(归并排序)||(树状数组+离散化)
- poj 2299 Ultra-QuickSort(利用树状数组变形,求一个数左边比它大的数的个数)
- poj--2299 Ultra-QuickSort(树状数组求逆序数)
- POJ2299 Ultra-QuickSort
- poj 2299 Ultra-QuickSort(求逆序数,树状数组)
- POJ 2299 Ultra-QuickSort (求序列的逆序对数)
- poj_2299 Ultra-QuickSort
- poj 2299 Ultra-QuickSort 求逆序数 树状数组解法
- [树状数组]POJ 2299 Ultra-QuickSort
- Ultra-QuickSort - POJ 2299 树状数组+离散化
- POJ 2299 Ultra-QuickSort 树状数组
- POJ 2299 Ultra-QuickSort(树状数组求逆序数)