【題解】[POJ 2352] Stars(樹狀數組)

題面

【題目描述】
天文學家常常檢查星星地圖,星星都有它的x,y座標,星星的等級的是左下方星星數量決定,包含正左和正下。
在這裏插入圖片描述
例如,看看上面的星圖。星星55的等級爲33 (由星星112244決定的)。星星22的等級爲11(由星星11決定的)。在這張地圖上0級的星星有一顆,11級的星星有兩顆,22級的星星有一顆,33級的星星有一顆,
你要編寫一個程序,計算每個等級的星星的數量。
【輸入】
第一行爲星星的數量NN。(1N150001 \leq N \leq 15000)
接下來NN行,每行爲星星的X,YX,Y座標,用空格來分開(0X,Y320000 \leq X,Y\leq 32000),每一個點上只有一個星星,按YY的升序給出座標,如果YY相同,則按照XX的升序給出。
【輸出】
輸出應該包含NN行,每行一個數字。第一行00級星星的數量,第二行11級星星的數量等等,最後一行包含n1n – 1星星的數量。
【樣例輸入】

5
1 1
5 1
7 1
3 3
5 5

【樣例輸出】

1
2
1
1
0

算法分析

乍一看好像是二維樹狀數組,但是本題降低了難度,對於輸入是按照:YY的升序給出座標,如果YY相同,則按照XX的升序給出。
那麼輸入第i顆星星的座標時,小於等於X[i]X[i],小於等於Y[i]Y[i],即左下角的星星已經全部出現了,且YY按照升序給出,因此,可以忽略YY座標,只需要找到小於等於X[i]X[i]的星星數量就是星星的級數。
設定數組a[x]a[x],表示XX座標爲x的星星個數。
找小於等於X[i]X[i]的星星,即找前綴和a[1] a[X[i]]a[1]~a[X[i]]
需要注意,題目下標從0開始,而樹狀數組不能有下標爲0的情況,所以整體右移動一位。
當然也可以用二維樹狀數組實現。
【程序實現】

#include<bits/stdc++.h>
using namespace std;
#define N 32100
using namespace std;
int n,c[N],s[N],x[N],y[N];
int lowbit(int x)
{
    return x&(-x);
}
void update(int x,int val)
{
    while(x<=32001)				//座標最大值爲32000 
    {
        c[x]+=val;
        x+=lowbit(x);
    }
}
int sum(int x)
{
    int ans=0;
    while(x>0)
    {
        ans+=c[x];
        x-=lowbit(x);
    }
    return ans;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&x[i],&y[i]);	//爲了避免出現0的情況,整體+1 
        s[sum(x[i]+1)]++;		// 統計前綴和 
        update(x[i]+1,1);			//單點增加 
    }
    for(int i=0;i<n;i++)
        printf("%d\n",s[i]);
    return 0;
 } 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章