poj 2352 Stars 用线段树实现 (有点水)

最近在学线段树,总感觉线段树的题目比较灵活,,用线段树的题目很容易和其他数据结构的题目区分开来。

URL:POJ:2352

这题主要在输入方面对做题很有优势,首先按y升序,y相同,按x升序。所以在考虑区间时,就可以只考虑x就可以。

这题如果用树状数组做的话,更容易,因为要统计区间内的星星数目。

废话不多说,上代码:

#include <stdio.h>
#include <string.h>
#define MAX 100000
#define MAX_POINT 32005
struct SegTree{
	int left,right;
	int count;
}st[MAX];
int level[MAX>>2];			//储存level的  
void creatTree(int left , int right , int pos)
{
	st[pos].left = left ;
	st[pos].right = right ;
	st[pos].count = 0 ;
	if(left == right)
	{
		return ;
	}
	int mid = (left + right)>>1;
	creatTree(left,mid,pos<<1);
	creatTree(mid+1,right,pos<<1|1);
}
void update(int x , int pos)		//更新区间,为什么只更新一个点呢,,因为如果更新一个区间的话,就会重复统计。只更新点所在的区间,方便统计  
{
	++st[pos].count ; 
	if(st[pos].left == st[pos].right && st[pos].right  == x)
	{
		return ;
	}
	int mid = (st[pos].left + st[pos].right)>>1;
	if(x > mid)
	{
		update(x,pos<<1|1);
	}
	else
	{
		update(x,pos<<1);
	}
}
int count(int left , int right , int pos)	//统计相同等级的星星个数    
{
	int sum = 0 ;
	if(st[pos].left == left && st[pos].right == right)
	{
		return st[pos].count ;
	}
	int mid = (st[pos].left + st[pos].right)>>1;
	if(left > mid)
	{
		sum += count(left,right,pos<<1|1);
	}
	else if(right <= mid)
	{
		sum += count(left,right,pos<<1);
	}
	else
	{
		sum += count(left,mid,pos<<1);
		sum += count(mid+1,right,pos<<1|1);
	}
	return sum ;
}
int main()
{
	int n ;
	while(scanf("%d",&n) != EOF)
	{
		int x , y;
		creatTree(0,MAX_POINT,1);
		memset(level,0,sizeof(int)*(MAX>>2));
		for(int i = 0 ; i < n ; ++i)
		{
			scanf("%d%d",&x,&y);
			level[count(0,x,1)]++;		//先找星星,再更新线段树    
			update(x,1);
		}
		for(int i = 0 ; i < n ; ++i)
		{
			printf("%d\n",level[i]);
		}
	}
	
	return 0;
}


你可能感兴趣的:(数据结构,线段树,poj2352)