今天學習下一種新的資料結構。
樹狀陣列 英文名字binary indexed tree.
樹狀陣列是為了方便對需要修改的區間進行求和的資料結構。
如果乙個陣列,需要對其求和,並且當陣列元素修改後仍需要對其求和,對這種需要修改,並且修改後需要求和的問題,可以採用樹狀陣列。樹狀陣列採用空間換時間的方式,當需要求和操作時,樹狀陣列並不需要遍歷整個陣列的操作,而是只需要計算少數幾個節點的和,就可以得到修改後所有陣列的和。
詳細參考。
樹狀陣列有個核心操作是lowbit
lowbit 作用:
設p是乙個數的二進位制表示中,從右往左數第乙個1的位置,或者說是乙個數二進位制表示中從右往左數遇到1為止,連續0的個數。
比如 4 二進位制 100 則p為2,
lowbit 求出的結果是2^p
int lowbit(int x)
那麼如何理解這個lowbit函式呢。
首先計算機中負數都是用補碼表示的。負數的補碼等於,保持符號位不變原碼取反並加1。
對於乙個數x,從右往左第乙個1位置為p,如果 x-1的話,在p以及包含p這個位置所有的數都和x相反。
如果x xor (x-1)
xor是異或)的話,則p之前的位都是0
因為x p位是1往後的所有位都是0,
如果 x&(x xor (x-1)) ,則除了p位是1,所有位都是0
而 -x的補碼表示 和 x xor (x-1) 是一樣的
所以一般用
x&(-x) 來實現lowbit
樹狀陣列的建立過程。
對於原來陣列 a, 樹狀陣列為c
陣列下標從1開始
對於下標i
if i%2==1 // i is odd
c[i]=a[i]
else // i%2==0
c[i]=a[i-2^k+1]+...+a[i]
// 其中 2^k 等於lowbit(i) k即是i從右往左數第一位1的位置,或者說0的個數。
對於陣列求和操作 求陣列前n個數的和
int
sum(n)
}
如果更新乙個陣列a[n] 則c[n]
更新操作
void change(int i,int x)
}
詳細參考部落格: 樹狀陣列1 樹狀陣列入門
仔細看一下,發現tree的每乙個節點的高度並不是隨意的,而是由它轉成二進位制之後末尾連續零的數量決定的,連續零的數量加1,就是高度,例如 3 11 零的數量為0,加1等於1,所以它的高度就是1 6 110 零的數量為1,加1等於2,所以它的高度就是2 8 1000 零的數量為3,加1等於4,所以它的...
樹狀陣列 瞎bb 樹狀陣列
樹狀陣列是乙個利用一維陣列和位運算組成的求解區間問題的高效資料結構,其構造如圖所示 首先,我們要用它解決單點修改 區間查詢的操作。根據這張圖我們建立乙個陣列bit,下標就是圖中顯示的十進位制數。bit i 就表示了圖中所示的一段區間的和,例如bit 6 sum 5,6 bit 4 sum 1,4 下...
樹狀陣列 二維樹狀陣列模板
樹狀陣列模板 int lowbit int x int add int x,int val int que int x 模板題 題解 include include include using namespace std int c 300000 rank 300000 int n int lowb...