poj2299 树状数组入门题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj2299 树状数组入门题相关的知识,希望对你有一定的参考价值。
题意:利用树状数组求逆序数;
思路:因为输入范围较大,先离散化一下,得到的数组a记录了原来数组的大小关系;然后按下标顺序执行add(a[i],1),这样sum(a[i])得到的就是小于等于a[i]的个数,i-sum(a[i])即为a[i]前面比a[i]大的数的个数 //外循环n次并累加i-sum(a[i])得到逆序数
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 typedef long long LL; 7 8 struct node{ 9 int v,order; 10 }a[500050]; 11 12 bool cmp(node a, node b){ 13 return a.v < b.v; 14 } 15 16 int aa[500050],c[500050]; 17 int n; 18 19 int lowbit(int x) 20 { 21 return x & (-x); 22 } 23 24 int sum(int x){ 25 int ret = 0; 26 while(x > 0) 27 { 28 ret += c[x]; x -= lowbit(x); 29 } 30 return ret; 31 } 32 33 void add(int x, int d){ 34 while(x <= n){ 35 c[x] += d; x += lowbit(x); 36 } 37 } 38 39 int main() 40 { 41 while(scanf("%d",&n) == 1 && n) 42 { 43 for(int i = 1; i <= n; ++i) 44 { 45 scanf("%d",&a[i].v); 46 a[i].order = i; 47 } 48 sort(a+1,a+n+1,cmp); 49 for(int i = 1; i <= n; ++i) 50 { 51 aa[a[i].order] = i; 52 } 53 memset(c,0,sizeof(c)); 54 LL ans = 0; 55 for(int i = 1; i <= n; ++i) 56 { 57 add(aa[i],1); 58 ans += i-sum(aa[i]); 59 } 60 printf("%lld\n",ans); 61 } 62 return 0; 63 }
以上是关于poj2299 树状数组入门题的主要内容,如果未能解决你的问题,请参考以下文章
POJ 2299 Ultra-QuickSort(树状数组+离散化)
poj 2299 Ultra-QuickSort 逆序对模版题
POJ 2299 -Ultra-QuickSort-树状数组求逆序数