POJ 2352 Stars 樹狀陣列

2021-08-25 18:43:02 字數 1516 閱讀 8025

樹狀陣列中,每個結點管轄了不同的原陣列元素的和。

令a[1...n]表示原陣列,c[1...n]表示樹狀樹組。

觀察圖,可知:

c1 = a1

c2 = a1 + a2

c3 = a3

c4 = a1 + a2 + a3 + a4

c5 = a5

c6 = a5 + a6

c7 = a7

c8 = a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8

...

c16 = a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + a11 + a12 + a13 + a14 + a15 + a16

這裡有乙個有趣的性質:

設結點編號為x,那麼這個節點管轄的區間有2^k(其中k為x二進位制末尾0的個數)個元素。因為這個區間最後乙個元素必然為a[x],所以很明顯:c[x] = a[x – 2^k + 1] + ... + a[x]。

算這個2^k有乙個快捷的辦法,定義如下乙個函式,返回x的2^k。

int lowbit(int x)

計算陣列a[1...x]的和,演算法如下:

step1: 令sum = 0,轉第二步;

step2: 假如x <= 0,演算法結束,返回sum值,否則sum = sum + c[x],轉第三步;

step3: 令x = x – lowbit(x),轉第二步。

函式如下:

int sum(int x)

return s;

}修改某個a[x]元素(將a[x]的值增加t),演算法如下:

step1: 當x > n時,演算法結束,否則轉第二步;

step2: c[x] = c[x] + t, x = x + lowbit(x)轉第一步。

函式如下:

void update(int x, int t)

}好了,來看poj這道題。

題意

乙個「*」的層次是這樣定義的,處於該「*」的下面和左面的範圍內的「*」的個數即為該「*」的層次。題目要求處於0到n-1層次的「*」數目各有幾個。

分析

由於「*」的座標已經按y遞增的順序排列好,對於具有相同y座標的「*」,又按其x座標排序,故可充分利用這一輸入特點,直接運用樹狀陣列進行求解。

**

#include #define max_stars 15005 #define max_coor 32005 int tree[max_coor]; int totalnumlev[max_stars]; /*返回c[n]所管轄的元素個數,即2k*/ int lowbit(int x) /*計算陣列a[1...x]的和* /int sum(int x) return s;} /*將a[x]的值增加t*/ void update(int x, int t) } int main() for(int i = 0; i < n; i++) return 0; }

樹狀陣列 poj2352 Stars

stars 題目 題意 在乙個二維陣列中統計某個等級星星的個數,星星的等級為不比此星星高且不在它右邊範圍內的星星個數。題解 因為輸入的資料已經排序,只要一邊接收輸入一邊計算等級即可。include includeusing namespace std int a 15005 c 32010 defi...

poj 2352 Stars(樹狀陣列)

題意 依次給出n個星星的座標 y座標以非遞減的順序輸入 對於每個星星,她的等級等於她左下方的星星的個數和 包括邊界上的星星 要求輸出等級0到等級n 1的星星的個數。0 x,y,32000,1 n 15000 設x i 表示橫座標為i的星星有多少顆,那麼對於乙個單一詢問 星星 k,y 的等級是多少?要...

poj 2352 Stars 樹狀陣列

我的第一道樹狀陣列哇咔咔 大一的時候怎麼都看不懂,也許我當時太不用心了吧。題意 給一些點的座標,每個點的level是看比它高度低且不在它右邊的點的個數。演算法 由於此題座標本來就是按y值從小到大,x值從小到大排列的。所以樹狀陣列中存座標為x的點的個數。每次讀入只要找1 x的sum,然後更新數量 1即...