樹狀陣列學習筆記

2022-03-15 14:57:39 字數 1779 閱讀 5951

參考自:

0. 介紹(來自wikipedia)

- 樹狀陣列, 又稱二分索引樹(binary indexed tree,bit), 用於高效計算數列的字首和.

- 它可以以

的時間得到

,並同樣以

對某項加乙個常數。

1. 資料結構定義

- 存放原始資料元素的陣列a (i.e.  int  a)

- 樹狀陣列 s   (i.e.   int s)

- 注意:

- 原始資料陣列 a 可能是隱含的, 因為 s[i] 中包含a[i], 而且也可以通過 s[i]-s[i-1] 來計算得到 a[i].

- 樹狀陣列s只是乙個維護 a 資訊的資料結構, 可能本身不對應實際的物理含義, 是一種抽象的結構.

2. 說明:

- s 和 a 的大小一樣大

- 當a全為0 的時候, s也全為0.

- s 的build 是基於維護a的, 但是a不一定是現成的, 有時候可能通過從0開始動態構建(參考題解poj 2352

).- 下標從 1 開始計算, 因為後面要用到二進位制格式末尾 連續0 的個數. 所以如果用 0 的話不太好處理.

3. 公式(2個等效的, 公式1用於理解, 計算主要用公式2)

-1.s[i]=a[i-2k+1]+a[i-2k+1+1]+......+a[i-1]+a[i]   (ifi-2k+1 < i)   

-2.s[i]=a[i] + s[j]   (j=i-1 decreasing toi-2k+1, j -=2t, t=lowbit(j)

)- s[i] 表示 樹狀陣列第i個元素,  並不是前 i 個元素的和.

- k 表示 i 的二進位制格式的末尾連續0的位數( i.e.    i=610=1102   => k = 1) , 也代表s[i] 在樹狀結構中的層數 (i.e.  s[6] 在 level 1,  from level 0).

- 2k 表示 s[i] 中包含原始資料 陣列 a 中的元素個數  如s[6] = a[5] + a[6], 因為 k=1,  2k為2, 利用公式計算得到 a[5] 和 a[6].  a[i-2k+1] 算出 a[5]為起始項.

4. 工具**

- 求 2k  值

int lowbit(int

x)

- 建立樹狀陣列

- 注意: 只有當原始資料陣列準備好之後才能用這個方法. 如果沒有, 應該使用動態構建(先初始化s, 然後根據條件構建s到完整的樹狀陣列).

//

根據原始資料陣列建立樹狀陣列 s

void

build()

}

- 查詢: 求前n項和, 繼而也可以求任意區間之和. (logn)

//

計算前n項和

int sumn (int

n)

- 修改: 修改元素資料並同步更新樹狀陣列的值.(logn)

//

原始陣列可以直接修改, 更新樹狀陣列需要將包含 a[i]的所有元素更新.

//@param index: 修改的元素的下標. a[i]的修改對s[i]以前的元素沒有影響.

//@param dalta : 修改量

void modify(int index, int

delta)

學習筆記 樹狀陣列

以下 為樹狀陣列最常用的幾個操作 1.low bi t mathrm lowbit function lowbit x longint int64 begin exit x and x end 2.單點修改 procedure replace x,y int64 var i int64 begin ...

樹狀陣列學習筆記

在學習完了線段樹後,聽說樹狀陣列能寫的題,線段樹都能做,所以一直沒有詳細的學習樹狀陣列 直到碰到了一道卡線段樹的題目,因為線段樹運用了很多遞迴,所以常數比較大,容易被卡 現在總結一下樹狀陣列 1 樹狀陣列個人認為就是字首和演變而來的 2 單點更新 當你要更新某個點的值時,你要從下面到上面依次更新過去...

樹狀陣列學習筆記

樹狀陣列 binary index tree,bit 也是很多人心中最簡潔優美的資料結構之一。最簡單的樹狀陣列支援兩種操作,時間複雜度均為 當然,樹狀陣列能維護的不侷限於加法,支援的操作也不止這兩種,甚至有大佬能用樹狀陣列實現平衡樹,但這篇筆記不會深入討論 因為我也還不是很懂 回顧一下,我們說,我們...