POJ-2352(Stars)树状数组解法

题目原网址:http://poj.org/problem?id=2352

又是一道星星的题,下面是题目描述(本人翻译):

题目描述

天文学家经常检查星图,其中恒星由平面上的点表示,每颗恒星都有笛卡尔坐标。让恒星的水平是恒星的数量,而恒星并不高于恒星的右边。天文学家想知道恒星的分布。

POJ-2352(Stars)树状数组解法_第1张图片

例如,查看上图中显示的地图。星号5的水平等于3(它由三颗星形成,数字为1,2和4)。而且,编号为2和4的恒星的等级为1.在该地图上,等级0中只有一颗恒星,等级1的两颗恒星,等级2的一颗恒星和等级3的一颗恒星。

你要编写一个程序来计算给定地图上每个级别星星的数量。


输入

输入文件的第一行包含许多恒星N(1 <= N <= 15000)。以下N行描述了恒星的坐标(由空格隔开的两行整数X和Y,0 <= X,Y <= 32000)。飞机一点上只能有一颗星。星号按照Y坐标的升序排列。 Y坐标相等的星号按照X坐标的升序排列。


输出

输出应该包含N行,每行一个数字。第一行包含0级星的数量,第二行包含第一级星的数量等,最后一行包含第N-1级的星的数量。


示例输入
5
1 1
5 1
7 1
3 3

5 5


示例输出
1
2
1
1

0

提示

这个问题有巨大的输入数据,使用scanf()而不是cin来读取数据,以避免超过时间限制。

这道题可以用树状数组和线段树解决。本人遵循能用树状数组就用树状数组的原则,因为代码实在比线段树简单,空间也不用开4n。

下面是AC代码(树状数组):

#include
using namespace std;
const int maxn=32005;
int bit[maxn],level[maxn],n,x,y;
int lowbit(int x)
{
	return x&-x;
}
void add(int x,int v)
{
	while(x<=maxn)
	{
		bit[x]+=v;
		x+=lowbit(x);
	}	
}
int sum(int x)
{
	int ans=0;
	while(x>0)
	{
		ans+=bit[x];
		x-=lowbit(x);
	}
	return ans;
}//树状数组
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d%d",&x,&y);
		level[sum(++x)]++;
		add(x,1);
	}
	for(int i=0;i<=n-1;i++)
	  printf("%d\n",level[i]);	
	return 0;
}
需要注意的地方:

level要从level[0]开始输出,因为总会有一个点的左下方没有星星。



你可能感兴趣的:(POJ-2352(Stars)树状数组解法)