POJ - 2352 树状数组

一、内容

  • 给定很多歌坐标代表每个星星,一个星星它的左边和下边围起来的区域里面有多少个星星代表它是那个等级,问你0–N-1个等级中各有多少个星星属于。

二、思路

  • 对坐标按照y从小到大进行排序,y相同的以x小的在前。 由于题目叫求左边和下边包含的星星的数量,按照y进行排序后,只需要用树状数组维护x坐标有多少个点即可。因为每次的点必然是大于或者等于上一个点的高度
  • 题目给出的坐标可能是0,所以对x坐标进行+1处理

三、代码

#include <cstdio>
#include <algorithm>
using namespace std;
//c是树状数组 
int n, c[32005], ans[15005]; 

struct N {
	int x, y;
}p[15005];

bool cmp(N a, N b) {
	if (a.y == b.y) return a.x < b.x;
	return a.y < b.y;
}

void update(int x, int v) {
	for (int i = x; i <= 32005; i += i & (-i)) {
		c[i] += v;
	}
} 

int query(int x) {
	int ans = 0;
	for (int i = x; i > 0; i -= i & (-i)) {
		ans += c[i];
	}
	return ans;	
}
int main() {
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		scanf("%d%d", &p[i].x, &p[i].y);
		//由于x坐标可能为0 所以进行++ 树状数组不能维护0这个点 
		p[i].x++;
	}	
	sort(p + 1, p + 1 + n, cmp);
	for (int i = 1; i <= n; i++) {
		ans[query(p[i].x)]++;
		update(p[i].x, 1);
	}
	for (int i = 0; i < n; i++) {
		printf("%d\n", ans[i]);
	}
	return 0;
} 
发布了343 篇原创文章 · 获赞 244 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_41280600/article/details/101100832