資料結構 樹狀陣列

2021-09-12 21:41:23 字數 1833 閱讀 6148

講到了線段樹,那就順便講講樹狀陣列吧。

假設乙個長度為 12 的線段樹,構建結果如下:

在區間求和問題上,在葉子節點,顯然劃線部分的值可以由父親節點 - 左端葉子節點得到。

那麼,這部分資訊就是冗餘的,沒有儲存的必要。

同理,可以推導出所有冗餘的部分如下:

那麼,去除冗餘部分後的結果如下:

給每乙個節點乙個編號。

我們假設i為每個節點的編號,l[i]為該節點包含多少個元素的資訊(就是區間內的元素之和)。

可以得到如下**。

再來看看其二進位制表示:

沒看出規律?

我們來分析一下:

節點節點二進位制

父節點父節點二進位制

節點 -> 父節點

10001

20010

0001 + 0001 = 0010

20010

40100

0010 + 0010 = 0100

30011

40100

0011 + 0001 = 0100

40100

81000

0100 + 0100 = 1000

50101

60110

0101 + 0001 = 0110

60110

81000

0110 + 0010 = 1000

以上增加的值對應表中的l[i]

從上可以看出當前節點i的父節點是i+(i的「最低位1」),一般稱之為低位技術:l[i] = i & (-i)

那麼i節點的父節點的序號為:i + l[i]

同樣的規律,可以推算出[1, i]的值的第乙個區間為 :i - l[i]

接下來上**:

/* 

* 假設樹狀陣列為 t,長度為 n,序號 [1, ..., n]

*/// 低位技術

#define lowbit(x) ((x)&(-(x)))

// 獲取區間 [1, x] 的和

intgetsum

(int x)

return ret;

}// 獲取區間 [x, y] 的和

intgetsum

(int x,

int y)

// 更新第 x 點的值

void

updateonenode

(int x,

int c)

}

資料結構 樹狀陣列

區間資訊的維護與查詢專題 樹狀陣列 1.問題 動態連續和查詢問題。給定乙個n個元素的陣列a1,a2,an,你的任務是設計乙個資料結構,支援以下兩種操作。add x,d 操作 讓ax增加d.query l,r 計算al al 1 ar.對普通陣列進行 一次修改或 特定區間 求和,時間複雜度為o n n...

資料結構 樹狀陣列

原陣列 字首和 範圍和 原陣列更改陣列元素在求和效率較低,引入樹狀陣列 假設原陣列a 樹狀陣列c 樹狀陣列 的三種操作 1.lowbit 子葉數 二進位制最低位的1代表多少 實現 int lowbit int n 求 lowbit x returnx x 2.update a i k 假設a i 是...

資料結構 樹狀陣列

include using namespace std const int maxn 1e2 4 int c maxn 編號從1開始 intlowbit int n intupdate int x,int value intsum int x intmain include using namesp...