HOJ 2678 Stars

天空中有很多星星,这些星星有一定等级,等级计算规则很简单。星星的等级等于该星星可统治的星星的个数。如果星星A(x1,y1,z1)可以通知星星B(x2,y2,z2),则x2≤x1,y2≤y1,z2≤z1。规定星星不可以自己统治自己

Input

多组case,每组case第一行输入一个整数N(1 ≤ N ≤ 15000),表示天空中星星的个数。

接着N行,每行输入三个整数X,Y,Z,用空格间隔,(0 ≤ X,Y,Z ≤ 1000)

Output

每组case对应一行输出,包括用空格间隔的N个整数,依次为a0,a1,...,ai,...,aN-1,其中ai表示具有等级i的星星的个数。

Sample Input

5
0 0 0
1 1 1
2 2 2
3 3 3
4 4 4

Sample Output

1 1 1 1 1

 

和vijos的1066很像,只不过这个要考虑的是在x保证有序的情况下,

y和z都在当前星星之下的个数。

所以要用二维树状数组进行查询

 

 

code

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define abs(x) ((x)>0?(x):-(x))
#define __max(a,b) ((a)>(b)?(a):(b))
#define __min(a,b) ((a)<(b)?(a):(b))
#define rep(i,repstt,repend) for(int i=repstt;i0;i-=lowbit(i))
		for(int j=y;j>0;j-=lowbit(j))
			ret+=c[i][j];
	return ret;
}
void update(int dc,int x,int y){
	for(int i=x;i<1002;i+=lowbit(i))
		for(int j=y;j<1002;j+=lowbit(j))
			 c[i][j]+=dc;
	return ;
}
int main(){
	//FIN
	//FOUT 
	while(cin>>n){
		INIT(ans,0);
		INIT(c,0);
		erep(i,1,n)
			scanf("%d%d%d",&f[i].x,&f[i].y,&f[i].z);
		sort(f+1,f+n+1,cmp);
		erep(i,1,n){
			ans[sum(f[i].y+1,f[i].z+1)]++;
			update(1,f[i].y+1,f[i].z+1);
		}
		rep(i,0,n){
			if(i)putchar(' ');
			printf("%d",ans[i]);
		}
		putchar('\n');
	}
	//INCLOSE
	//OUTCLOSE
	return 0;
}


 

你可能感兴趣的:(HOJ 2678 Stars)