题目大意

 
    给出N个点的坐标,求出覆盖点的个数分别为0, 1, ... N-1 的点各有多少个。

题目分析

 
2. 更新到叶子节点的时候,叶子节点的w值加1,然后通过pushup操作,更新到父节点

实现(c++)

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<algorithm>

#define MIN(a, b) a <b? a:b
#define MAX(a, b) a >b? a :b
#define MAX_NUM 32005
#define MAX_NODE 15005
struct Point{
	int x;
	int y;
};
Point gPoints[MAX_NODE];
int gCoverNum[MAX_NODE]; //覆盖i个点的点的数目用 gCoverNum[i]表示
struct TreeNode{
	int beg;
	int end;
	int w;	//表示该节点所代表区间中被插入的点的个数,初始为0,之后每次插入时候,从上往下依次增加
	int Mid(){
		return (beg + end) / 2;
	}
	TreeNode(){
		beg = end = w =  0;
	}
};

TreeNode gTreeNodes[MAX_NUM * 4];

//初始化建树,主要初始化节点的边界和w
void BuildTree(int node, int left, int right){
	gTreeNodes[node].beg = left;
	gTreeNodes[node].end = right;
	gTreeNodes[node].w = 0;
	if (left == right){
		return;
	}
	int mid = (left + right) / 2;
	BuildTree(2*node + 1, left, mid);
	BuildTree(2*node + 2, mid + 1, right);
}

void PushUp(int node){
	gTreeNodes[node].w = (gTreeNodes[2 * node + 1].w + gTreeNodes[node * 2 + 2].w);
}

//向以node为根的树中插入x,沿途中经过的节点的w值均加1
void Insert(int node, int x){
//	gTreeNodes[node].w++;
	if (gTreeNodes[node].beg == gTreeNodes[node].end){
		//不在上面 gTreeNodes[node].w++;,则在这里执行,这样在最后执行 pushup操作。其效果和 开始的时候执行gTreeNodes[node].w++;一样
		gTreeNodes[node].w++;
		return;
	}
	int mid = gTreeNodes[node].Mid();
	if (x > mid){
		Insert(2 * node + 2, x);
	}
	else
		Insert(2 * node + 1, x);

	//如果不使用上面的  	gTreeNodes[node].w++;,则可以使用 PushUp操作,从下往上更新(由于递归的性质,会使得从叶节点到根都会被更新)
	//也就相当于 从上往下插入的时候,每经过一个点都将 w 值加 1
	PushUp(node);  
}

//在以node节点为根的树中查询区间 [s, e]中的元素数目
int Query(int node, int s, int e){
	if (gTreeNodes[node].beg > e || gTreeNodes[node].end < s){
		return 0;
	}
	if (gTreeNodes[node].beg >= s && gTreeNodes[node].end <= e){
		return gTreeNodes[node].w;
	}
	int mid = gTreeNodes[node].Mid();
	int sum = 0;
	sum += Query(2 * node + 1, s, MIN(mid, e));
	sum += Query(2 * node + 2, MAX(s, mid + 1), e);
	return sum;
}
int main(){
	int n;
	scanf("%d", &n);
	int max_end = 0;
	for (int i = 0; i < n; i++){
		scanf("%d%d", &gPoints[i].x, &gPoints[i].y);
		max_end = MAX(max_end, gPoints[i].x);
		gCoverNum[i] = 0;
	}
	BuildTree(0, 0, max_end);
	for (int i = 0; i < n; i++){
		int count = Query(0, 0, gPoints[i].x);
		gCoverNum[count] ++;
		Insert(0, gPoints[i].x);
	}
	for (int i = 0; i < n; i++){
		printf("%d\n", gCoverNum[i]);
	}
	return 0;
}

 

相关文章:

  • 2021-09-01
  • 2021-06-11
  • 2021-08-18
猜你喜欢
  • 2021-12-02
  • 2021-09-28
  • 2021-09-30
  • 2021-09-08
  • 2021-07-15
  • 2021-12-04
  • 2021-06-06
相关资源
相似解决方案