1. 程式人生 > >題解報告:hdu 1541 Stars(BIT)

題解報告:hdu 1541 Stars(BIT)

圖片 += .cn lowbit 數加 需要 nts ret scrip

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.

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,因為輸入的橫坐標大小不是在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 }

題解報告:hdu 1541 Stars(BIT)