POJ 2352(順路講解一下樹狀陣列)

2021-07-05 10:10:19 字數 2294 閱讀 4074

接觸到的第一道樹狀陣列的題,ac之後感覺對樹狀陣列思想的理解明顯清晰了很多,入門必備呀。

先來講講樹狀陣列吧。

上個圖

如果要求區間和,例如求a3->a8,我們先用陣列c來記錄下來各個區間的和,那麼就可以直接c8-c2就可以得到a3->a8的區間和了。

c[n]陣列的下標是用來記錄陣列a[1]->a[n]的區間和。

再想,我們如果要求s->t的和可以怎麼求?

是不是可以用(1->t)減去(1->s-1)?

同理,樹狀陣列也可以用這種方式求和。比如求a[2]的話就可以用c[2]-c[1]來得到a[2]。

關於c陣列的記錄方法,就不得不提到x&(-x)這個表示式。

x&(-x)是用來計算每次查詢或者更新時候c陣列的偏移量。

通常寫成函式的形式。

int lowbit(int x)

注意:計算機中負數是用的補碼表示的,正數是用的原碼表示,可以自己拿張草稿紙來實現一下x&(-x)的計算

關於樹狀陣列的求區間和,如果求區間[1,8],那麼直接c[8]就好,但是如果要求區間[4,8]該怎麼辦?

那麼可以用區間[1,8]的和減去區間[1,3]的和就得到了區間[4,8]的和。

那又如何求區間[1,3]呢?我們可以c[2]+c[3]就得到了區間[1,3]的和了。

下面是求區間[1,x]和的函式:

int sum(int x)

return s;

}

以求區間[1,3]為例,首先x等於3代入方程,3 > 0,則s = c[3],然後執行x-=lowbit(x);

讓我們進入lowbit函式,首先3的二進位制原碼為0000 0011,-3為3的補碼,則-3的二進位製碼為1111 1101,進行&運算之後為1,所以x-=1,此時x為2。由於2>0,所以s此時等於c[3] + c[2]。執行x-=lowbit(x)之後x = 0。迴圈結束,此時s已經是區間[1,3]的和了。

我們再來看樹狀陣列的更新函式:

int update(int x, int num)

}

和線段樹一樣,樹狀陣列也是需要對節點所影響到的所有節點進行更新,採取從根到頂的方式。也就是對每個影響到的節點都加上更改資訊。

樹狀陣列時間複雜度o(log n)

————————————————————————分割線——————————————————————————————

題意:有n個星星節點,存在星星節點左下角(包括正左和正下)的其他星星節點,則該星星節點比它左下角的星星節點大,level 0表示該星星節點沒有比他還小的節點,level 1表示存在乙個比該星星節點小的點。輸出統計好的每個level等級存在多少星星節點。

解題思路:為什麼要用樹狀陣列呢,因為如果你用for迴圈統計的話,由於資料很大然後又有很多組資料需要統計,那麼肯定是會超時的,所以此時需要一種高效的資料結構(感覺像一句廢話tat),樹狀陣列類似於線段樹,能夠很高效的解決區間問題,將這道題提煉一下其實也就是乙個統計區間和的問題,線段樹寫起來好麻煩的=。=於是乎用了樹狀陣列。

直接上**:

/*因為是按照y公升序輸入,所以後面輸入對前面輸入並無影響

**前x與後x如果相同,那麼肯定後x是包含前x的,因為是按照y公升序

**即前後x雖是在同一列,但後x肯定在前x上面,即包含前x

**ps:樹狀陣列下標從1開始

*/#include #include #include using namespace std;

int level[32001];

int c[32001];

int lowbit(int x)

int sum(int x)

return s;

}int update(int x)

}int main()

for (int i = 0; i <= n - 1; i++)

printf("%d\n", level[i]);

}return 0;

}

poj 2352 樹狀陣列

這道題好像被賤做了,看起來像二維的樹狀陣列,其實只是一維的,可能是資料太大了,矩陣開不那麼大,因為題意是求乙個矩陣中做它左下部分的個數,而去輸入的順序是按y公升序,後x公升序輸入。其實如果不按這個順序可以下排序。然後就是一維的樹狀陣列的思路了。轉個圖,可以知道它的這陣列性質了 include inc...

poj 2352 樹狀陣列

第一次做樹狀陣列的題,還是遇到了一點小麻煩,吃一塹長一智。對於樹狀陣列來說,下標不能從0開始,否則就死迴圈了。因為0 lowbit 0 0 就死迴圈下去了。其他的就沒什麼了,其實這道題就看x值,而且題意還給排好序了。直接計算就ok了。如下 include include include includ...

poj2352 樹狀陣列

題意 求0 n級別的星星的個數 以每乙個星星為原點建立平面直角座標系,在當前座標系第三象限的星星的個數看做乙個星星的級別數 include include include include include include include include include include using na...