Stars POJ - 2352(树状数组)

问题:Stars POJ - 2352

输入点的坐标,记录一个点的相关值,相关值定义为横纵坐标都小于等于这一点的点的个数,最后输出的时候,输出n行,第i行是相关值是i-1的点的个数,输入保证y坐标递增,y相同情况下,x坐标递增

分析:

首先由于输入数据具有递增型,可以不储存数据,来一个分析一个,而且由于y是递增的,所以后加入的点在y方向上就不用再检查是否满足条件了,也就是说我们只用看当前点的x坐标之前(包括x)的点的个数就可以了,这就具有了树状数组的求区间和的需要。每输入一个点,考察它的x坐标,即计算getsum(x),getsum(x)就是这个点的相关值,只需把sum[getsum(x)]++,就是把相关值为getsum(x)的点数++,计算完了之后,再add(x),即x这一坐标的点再加一个,如此往复,最后输出sum[]即可

但是!!!注意x可以从0开始……树状数组是处理不了add(0)的,所以输入x以后要x++

代码:

#include<iostream>
#include<cstring>
using namespace std;
#define MEM(a) memset(a,0,sizeof(a))
#define UP(i,x,y) for(int i=x;i<=y;i++)  
#define DOWN(i,x,y) for(int i=x;i>=y;i--)  
const int num=32000;
int c[num+10],sum[num+10];
void add(int i){
	while(i<=num+10){
		c[i]++;
		i+=i&(-i);
	}
}
int getsum(int i){
	int s=0;
	while(i>0){
		s+=c[i];
		i-=i&(-i); 
	}
	return s;
}
int main(){
	int n;
	while(cin>>n){
		MEM(c);MEM(sum);
		int x,y;
		UP(i,1,n){
			scanf("%d %d",&x,&y);
			x++;
			sum[getsum(x)]++;
			add(x);
		}
		UP(i,0,n-1){
			printf("%d\n",sum[i]);
		} 
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41333528/article/details/80274562