HDU 2689 Sort it 求逆序数,树状数组实现

最近在看树状数组,看了很长时间,理解的还是很透。

总感觉树状数组很神奇,特别是那段lowbit()函数,简直是妙不可言啊!

为了验证自己看的知识,所以就刷了一道水题,真的是很水的一道题,求逆序数的,在之前,我都是用归并求逆序数的,我记得是0ms通过

今天用了树状数组,也是0ms.

由于树状数组看的不太明白,所以不敢再这多言,怕误导了大家。因为实在是被他的神奇之处所震撼了,短短的十几行代码,就可以完成那么炫酷的事情,真的让人欲罢不能啊!

接下来来我就谈谈我自己的见解,树状之间是通过一个函数完成的,那就是lowbit(),如果你没学过树状数组的话,那接下来的你会惊呆。。下面是lowbit()的源码:

int lowbit(int x)
{
	return x&(-x) ;
}
是的,你没有看错,,他就只有一行,但是想要理解这行,可得花费很大的时间。鉴于篇幅,就不在详细赘述了详细请见:<a target=_blank href="http://blog.csdn.net/int64ago/article/details/7429868">点击打开链接</a>。
<pre name="code" class="cpp">index +=  lowbit(index) //访问父节点
index -= lowbit(index)  //访问子节点

 hdu:2689 Sort it 点击打开 
 

这题就是求逆序数的,关于怎么用树状数组求逆序数,且听我解释,,由于题目告知,序列中无重复数字。所以,我们可以转化一下思路,逆序数是指这个数它后面有多少个数比它小的,可以等价为求这个数前面有多少比他大的就行了,由于求比他大的太浪费时间,,所以求比他的小的数量,在转化一下就可以了,具体转化:index-sum(index);其中index为为这个数在序列中位置,sum(index)是指index前面比他小的数的数目之和。

代码:

#include <stdio.h>
#include <string.h>
#define MAX 1005
int a[MAX] ;
int lowbit(int x)
{
	return x&(-x) ;
}
void update(int pos)
{
	while(pos <= MAX)
	{
		a[pos]++ ;
		pos += lowbit(pos);
	}
}
int sum(int pos)
{
	int s = 0 ;
	while(pos > 0)
	{
		s += a[pos] ;
		pos -= lowbit(pos) ;
	}
	return s ;
}

int main()
{
	int n ;
	while(~scanf("%d",&n))
	{
		memset(a,0,sizeof(int)*MAX);
		int pos , s = 0;
		for(int i = 0 ; i < n ; ++i)
		{
			scanf("%d",&pos);
			update(pos);
			int t = sum(pos-1) ;
			s += i-t;
		}
		printf("%d\n",s);
	}
	return 0 ;
}

如有不懂的,可以点击: 点击打开链接

或者:点击打开链接

你可能感兴趣的:(数据结构,it,sort,树状数组,hdu2689)