ural 1028 Stars [线段树]

题意:给n个星星的坐标(x,y),其中1 ≤ N ≤ 15000,0 ≤ X,Y ≤ 32000,定义星星的等级为在它的左下方的星星的数目(横纵坐标均可相等),要求输出等级为0~n-1的星星的数目

思路:首先不可能暴力两重循环,自然是线段树。由于给的星星是按照纵坐标的升序排列的,只要一维地对x做处理就行了。

线段树跟堆好像23333~

#include 
#include 
struct Node
{
	int a, b, cover;
	Node() {}
	Node(int _a, int _b): a(_a), b(_b), cover(0) {}
	int middle() { return (a+b)>>1; }
} t[66000];

void build(int a, int b, int d)
{
	t[d] = Node(a,b);
	if (a >= b) return ;
	int mid = (a+b) >> 1;
	build(a,mid,2*d+1);
	build(mid+1,b,2*d+2);
}
void add(int n, int d)
{
	t[d].cover ++;
	if (t[d].a == t[d].b) return ;
	int mid = t[d].middle();
	if (mid >= n) add(n, 2*d+1);
	else add(n,2*d+2);
}
int quary(int a, int b, int d)
{
	if (a==t[d].a && b==t[d].b) return t[d].cover;
	int mid = t[d].middle();
	if (mid >= b) return quary(a,b,2*d+1);
	else if (mid < a) return quary(a,b,2*d+2);
	else return quary(a,mid,2*d+1) + quary(mid+1,b,2*d+2);
}
int num, x, y;
int level[15005];
int main()
{
	while (scanf("%d",&num) != EOF)
	{
		memset(level,0,sizeof(level));
		build(0,32000,0);
		for (int i = 0; i < num; ++ i)
		{
			scanf("%d%d",&x,&y);
			level[quary(0,x,0)] ++;
			add(x,0);
		}
		for (int i = 0; i < num; ++ i)
			printf("%d\n", level[i]);
	}
}


你可能感兴趣的:(ural 1028 Stars [线段树])