樹狀陣列入門

2022-08-11 03:15:13 字數 2332 閱讀 2160

今天來討論下樹狀陣列

來觀察這個圖:

令這棵樹的結點編號為c1,c2...cn。令每個結點的值為這棵樹的值的總和(就是c[n]表示陣列a從第一項一直加到n項的和,比如c4,它就是c[4]=a[1]+a[2]+a[3]+a[4]=10,和圖中所存資料相同),那麼容易發現:

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

從圖中不難發現,c[k]儲存的實際上是從k開始向前數k的二進位制表示中右邊第乙個1所代表的數字個元素的和(這麼說可能有點拗口,令lowbit為k的二進位制表示中右邊第乙個1所代表的數字,然後c[k]裡存的就是從a[k]開始向前數lowbit個元素之和)

這麼存有什麼好處呢?無論是樹狀陣列還是線段樹,都用到了分塊的思想,而樹狀陣列採用這樣的儲存結構我想最主要的還是這樣方便計算,我們可以用位運算輕鬆地算出lowbit.分析一下這樣做的複雜度:對於更改元素來說,如果第i個元素被修改了,因為我們最終還是要求  和,    所以可以直接在c陣列裡面進行相應的更改,如圖中的例子,假設更改的元素是a[2],那麼它影響到得c陣列中的元素只有c[2],c[4],c[8],我們只需一層一層往上修改就可以了,這個過程的最壞的複雜度也不過o(logn);對於查詢來說,如查詢s[k],只需查詢k的二進位制表示中1的個 數次就能得到最終結果,比如查詢s[7],7的二進位制表示中有3個1,也就是要查詢3次,到底是不是呢,我們來看上圖,s[7]=c[7]+c[6]+c[4],可能你還不知道怎麼實現這個過程.

還以7為例,二進位制為0111,右邊第乙個1出現在第0位上,也就是說要從a[7]開始向前數1個元素(只有a[7]),即c[7]; 

然後將這個1捨掉,得到6,二進位制表示為0110,右邊第乙個1出現在第1位上,也就是說要從a[6]開始向前數2個元素(a[6],a[5]),即c[6];

然後捨掉用過的1,得到4,二進位制表示為0100,右邊第乙個1出現在第2位上,也就是說要從a[4]開始向前數4個元素(a[4],a[3],a[2],a[1]),即c[4].

樹狀陣列我們可以把它理解為一種儲存資料的特殊資料結構,與普通的陣列相似都是用於儲存資料,但與普通陣列不相同的地方在於,比如我想算第1項到第7項的和,普通陣列必須sum+=a[i](sum初始化為0,1=

樹狀陣列的模板**實現:

intlowbit(

intx)

//計算lowbit,需要特別注意下x一般不能等與0,因為 0&(-0)=0。

void

add(

inti,

intval)

//將第i個元素的值加上val

}intsum(

inti)

//求前i項和

return

s;}根據上面的函式模板,我具個簡單的例子,加深下對樹狀陣列的理解

題目大意:比如說有5個兵營地,開始時給出了每個兵營地的初始值(我們就假設每個兵營地的人數為1人),接下來我們可以有下面幾個操作1.向第i個(1=

首先拿到這個問題後,你可能會覺得這題直接用普通陣列就能實現,但是如果我們將兵營地的數量擴充到50000,對於操作的次數我們也取乙個很大的值,也就是說我們需要頻繁的在乙個數量個數特別大的營地裡進行加入,減少,和查詢的操作,而時間我們也卡得很緊,普通陣列一般方法實現的話一定會超時,這時你想到了什麼呢?沒錯,這個性質不就適合樹狀陣列嗎(當然線段樹也能很好的實現,線段樹的相關知識我以後再更新)。

重新回到題目,假設我們一共接到了3條命令,<1>向第3個營地裡加入2人 <2>向第5個營地裡減少1人 <3>查詢第1個營地到第5個營地的人數總和。

我們用陣列c[i]=1(1=我們直接使用 add(3,2),此時陣列c更新為了c[1]=1,c[2]=1,c[3]=3,c[4]=3,c[5]=1  <2>add(5,-1) 此時陣列更新為c[1]=1,c[2]=1,c[3]=3,c[4]=3,c[5]=0  <3>sum(5) 此時就得出了結果    

這篇隨筆就是簡單的介紹下樹狀陣列吧,後面我也會慢慢的把做過的樹狀陣列的題目解題報告貼到上

樹狀陣列1 樹狀陣列入門

仔細看一下,發現tree的每乙個節點的高度並不是隨意的,而是由它轉成二進位制之後末尾連續零的數量決定的,連續零的數量加1,就是高度,例如 3 11 零的數量為0,加1等於1,所以它的高度就是1 6 110 零的數量為1,加1等於2,所以它的高度就是2 8 1000 零的數量為3,加1等於4,所以它的...

樹狀陣列 入門

樹狀陣列,乙個用來區間求和修改都為log n 的演算法。在網上資料很多,看起來也不是很難,學習一下!基本上學習樹狀陣列都會看到下面這個圖,這也是最基本的乙個圖,看懂這個以後,對樹狀陣列也就會有 一定的了解了。令這棵樹的結點編號為c1,c2.cn。令每個結點的值為這棵子樹的值的總和,那麼容易發現 c1...

樹狀陣列入門

用office做了一張pdf 這是一維的情形,如果是二維,可以把每一行的一維樹狀陣列看成乙個節點,然後再把二維樹狀陣列看成一維樹狀陣列。好文章 兩道入門題 對於第一題hdu1556 題意 初始陣列元素值都為0,給定區間 x,y 將區間 x,y 每個元素的值 1,最後輸出整個陣列每個元素的值。更新區間...