hdu 1541 Stars(经典BIT)
Problem Description
Astronomers often examine star maps where stars are represented by points on a plane and each star has Cartesian coordinates. Let the level of a star be an amount of the stars that are not higher and not to the right of the given star. Astronomers want to know the distribution of the levels of the stars.
For example, look at the map shown on the figure above. Level of the star number 5 is equal to 3 (it's formed by three stars with a numbers 1, 2 and 4). And the levels of the stars numbered by 2 and 4 are 1. At this map there are only one star of the level 0, two stars of the level 1, one star of the level 2, and one star of the level 3.
You are to write a program that will count the amounts of the stars of each level on a given map.
For example, look at the map shown on the figure above. Level of the star number 5 is equal to 3 (it's formed by three stars with a numbers 1, 2 and 4). And the levels of the stars numbered by 2 and 4 are 1. At this map there are only one star of the level 0, two stars of the level 1, one star of the level 2, and one star of the level 3.
You are to write a program that will count the amounts of the stars of each level on a given map.
Input
The first line of the input file contains a number of stars N (1<=N<=15000). The following N lines describe coordinates of stars (two integers X and Y per line separated by a space, 0<=X,Y<=32000). There can be only one star at one point of the plane. Stars are listed in ascending order of Y coordinate. Stars with equal Y coordinates are listed in ascending order of X coordinate.
Output
The output should contain N lines, one number per line. The first line contains amount of stars of the level 0, the second does amount of stars of the level 1 and so on, the last line contains amount of stars of the level N-1.
Sample Input
5
1 1
5 1
7 1
3 3
5 5
Sample Output
1
2
1
1
0
解题思路:题目的意思就是每一颗星星都有一个等级level,其大小取决于以它为坐标原点,位于第三象限且包括x、y的负半轴(不算本身一点)内星星的个数,要求输出每个等级level(0~n-1)有多少个星星。典型的树状数组裸题!题目输入中已经规定:①不会有重点;②纵坐标先按升序排列;③如果纵坐标相同,按横坐标升序排列。简单在纸上模拟一下题目中的样例可知,我们只需对横坐标进行处理即可。其中有两点需要注意:一、单点修改update函数中while条件要为x<=32000(<maxn),因为输入的横坐标大小不是在n的范围内,所以要对整个大区间进行修改;二、由于输入的横坐标可能为0,而在树状数组中下标最小为1,如果不将输入的每个横坐标加1,那么在单点修改时,由于lowbit(0)==0,那么x小于maxn这个条件就会一直为true,即陷入死循环。
AC代码:
1 #include<string.h> 2 #include<cstdio> 3 const int maxn=32005; 4 int n,a,b,aa[maxn],tmp[maxn]; 5 int lowbit(int x){ 6 return x & -x; 7 } 8 void update(int x,int val){ 9 while(x<maxn){//注意:因为输入的横坐标大小不是在n的范围内,所以这里要小于或等于32000,对整个区间进行统计 10 aa[x]+=val; 11 x+=lowbit(x); 12 } 13 } 14 int get_sum(int x){ 15 int ret=0; 16 while(x>0){ 17 ret+=aa[x]; 18 x-=lowbit(x); 19 } 20 return ret; 21 } 22 int main(){ 23 while(~scanf("%d",&n)&&n){ 24 memset(tmp,0,sizeof(tmp));//tmp[i]表示等级level i有tmp[i]个星星 25 memset(aa,0,sizeof(aa));//注意清0 26 for(int i=0;i<n;++i){ 27 scanf("%d%d",&a,&b);//题目中的输入已排好序,直接对横坐标进行处理,get_sum(a+1)表示当前坐标点的左下角有这么多个星星,对应为level大小,其个数加1,即tmp[get_sum(a+1)]++; 28 tmp[get_sum(a+1)]++;//每个横坐标要加1,因为输入的横坐标可能为0,而在树状数组中下标最小为1,如果不加1,在单点修改的时候,由于lowbit(0)==0,那么x就会一直小于maxn,即陷入死循环 29 update(a+1,1);//当前坐标点对应level包含星星的个数先加1,因为不包括本身,所以再更新标记当前坐标点为1,即已经出现过 30 } 31 for(int i=0;i<n;++i)//输出每个level包含星星的个数 32 printf("%d\n",tmp[i]); 33 } 34 return 0; 35 }