树状数组的离散化 Ultra-QuickSort
2013-08-19 18:43
323 查看
离散化,但数据范围太大是所借用的利器,举个例子,有四个数99999999 1 123 1583 数据范围太大,而树状数组中的c数组开的范围是数据的范围,这时候就需要离散化,把四个数一次标号为1 2 3 4(即第一个数,第二个数。。。),按键值排序之后 依次为2 3 4 1(即从小到大排序为第二个数,第三个数。。。),所以,第二个数是最小的,即f[2]=1,f[3]=2,f[4]=3,f[1]=4,也就是把键值变为了1~n,相对大小还是不变的,即4 1 2 3。比如要求原来四个数的逆序数总和,现在就是求4 1 2 3的逆序数总和,大大节省了空间压力(树状数组的长度是数据范围)
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define MAX 500004 int c[MAX],f[MAX]; struct lisan{ int v,num; }a[MAX]; int get_val() { int ret(0); char c; while((c=getchar())==' '||c=='\n'||c=='\r'); ret=c-'0'; while((c=getchar())!=' '&&c!='\n'&&c!='\r') ret=ret*10+c-'0'; return ret; } int cmp(lisan a,lisan b) { return a.v<b.v; } int n; int lowbit(int x) { return x&(-x); } void update(int x,int num) { while(x<=n) { c[x]+=num; x+=lowbit(x); } } int get_sum(int x) { int s=0; while(x>=1) { s+=c[x]; x-=lowbit(x); } return s; } int main() { int i; while(scanf("%d",&n),n) { memset(c,0,sizeof(c)); for(i=1;i<=n;i++) { a[i].v=get_val(); a[i].num=i; } sort(a+1,a+1+n,cmp); for(i=1;i<=n;i++) f[a[i].num]=i; __int64 sum=0; for(i=1;i<=n;i++) { update(f[i],1); sum+=i-get_sum(f[i]); } printf("%I64d\n",sum); } return 0; }
相关文章推荐
- POJ Ultra-QuickSort (树状数组+离散化)
- poj-2299-Ultra-QuickSort-(树状数组and离散化)
- POJ 2299 Ultra-QuickSort 【树状数组 离散化 逆序对】
- POJ 2299 Ultra-QuickSort(树状数组+离散化)
- Ultra-QuickSort 学习归并排序(树状数组+离散化)
- poj2299:Ultra-QuickSort(树状数组+离散化)
- Ultra-QuickSort(离散化+树状数组求逆序数)
- POJ 2299 Ultra-QuickSort(树状数组+离散化处理)
- Ultra-QuickSort (树状数组离散化)
- Ultra-QuickSort 【归并或树状数组+离散化】
- poj 2299 Ultra-QuickSort (树状数组+离散化)
- 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(树状数组+离散化)
- 【树状数组--求逆序数(离散化)】poj2299 Ultra-QuickSort