二元索引樹

Binary Indexed Tree
Ruby@NTUIM

內容大綱

Ruby@NTUIM

實際應用

運作方式

運作原理

程式實作

二元索引樹

Ruby@NTUIM

實際應用

二元索引樹

Ruby@NTUIM

二元索引樹 > 實際應用

前綴和 Prefix Sum
7 5 8 3 -4 6 9 2
Naive
\text{O}(n)
Ruby@NTUIM

二元索引樹 > 實際應用

前綴和 Prefix Sum
7 5 8 3 -4 6 9 2

7

12

20

23

19

25

34

36

Accumulative
\text{O}(1)
Ruby@NTUIM

二元索引樹 > 實際應用

區間和 Range Sum
7 5 8 3 -4 6 9 2
Ruby@NTUIM

二元索引樹 > 實際應用

區間和 Range Sum
7 12 20 23 19 25 34 36
7 5 8 3 -4 6 9 2
Ruby@NTUIM

二元索引樹 > 實際應用

發現問題
7 5 8 3 -4 6 9 2
7 12 20 23 19 25 34 36
Ruby@NTUIM

二元索引樹 > 實際應用

發現問題
7 5 8 3 -4 9 2

16

7 12 20 23 19 25 34 36
Ruby@NTUIM

二元索引樹 > 實際應用

發現問題
7 5 8 3 -4 9 2

16

7 12 20 23 19

25

34

36

Ruby@NTUIM

二元索引樹 > 實際應用

發現問題
7 5 8 3 -4 9 2

16

7 12 20 23 19

35

34

36

Ruby@NTUIM

二元索引樹 > 實際應用

發現問題
7 5 8 3 -4 9 2

16

7 12 20 23 19

35

44

36

Ruby@NTUIM

二元索引樹 > 實際應用

發現問題
7 5 8 3 -4 9 2

16

7 12 20 23 19

35

44

46

Ruby@NTUIM

二元索引樹 > 實際應用

單點修改 Point Update
7 5 8 3 -4 9 2

16

7 12 20 23 19

35

44

46

\text{O}(n)
Ruby@NTUIM

二元索引樹 > 實際應用

解決方案 Solution
二元索引樹
Binary Indexed Tree
  • Prefix Sum Quries
  • Point Updates
  • Range Updates
  • Constrution
\text{O}(\log n)
\text{O}(\log n)
\text{O}(\log n)
\text{O}(n\log n)
Ruby@NTUIM

實際應用

二元索引樹

內容大綱

Ruby@NTUIM

實際應用

運作方式

運作原理

程式實作

二元索引樹

Ruby@NTUIM

運作方式

二元索引樹

Ruby@NTUIM

二元索引樹 > 運作方式

前綴和查詢 Prefix Sum Quries
\text{令 }\mathbf A\text{ 為一數列} \\ \text{令 }S_n\text{ 為 }\mathbf A\text{ 前 }n\text{ 項和 } \\ S_n=\sum\limits_{i=1}^n \mathbf A_i \\
Ruby@NTUIM

二元索引樹 > 運作方式

前綴和查詢 Prefix Sum Quries
\text{給定一棵基於 }\mathbf A\text{ 的所建構的二元索引樹,則} \\ S_n=\text{「第 N 號節點至根節點之路徑權重總和」} \\
Ruby@NTUIM

二元索引樹 > 運作方式

前綴和查詢 Prefix Sum Quries
\text{令 }\mathbf{BIT}\text{ 一棵基於 }\mathbf A\text{ 建構之二元索引樹} \\ \mathbf{BIT}_i\text{ 為第 } i \text{ 號節點之權重}
Ruby@NTUIM

二元索引樹 > 運作方式

前綴和查詢 Prefix Sum Quries
S_2=\mathbf{BIT}_2
S_5=\mathbf{BIT}_5+\mathbf{BIT}_4
S_{11}=\mathbf{BIT}_{11}+\mathbf{BIT}_{10}+\mathbf{BIT}_8
S_{12}=\mathbf{BIT}_{12}+\mathbf{BIT}_8
S_{15}=\mathbf{BIT}_{15}+\mathbf{BIT}_{14}+\mathbf{BIT}_{12}+\mathbf{BIT}_8
S_7=\mathbf{BIT}_7+\mathbf{BIT}_6+\mathbf{BIT}_4
S_n=\text{「第 N 號節點至根節點之路徑權重總和」}
Ruby@NTUIM

二元索引樹 > 運作方式

單點修改 Point Updates
\text{若修改 }\mathbf A_i\text{ 則要對 }\mathbf{BIT}\text{ 第 }i\text{ 之右兄弟節點及其父節點之右兄弟節點}
Ruby@NTUIM

二元索引樹 > 運作方式

建構 Construction
1. 將 BIT 始化所有節點初始化為 0
2. 對陣列的每個位置作單點更新
\text{O}(n\log n)
複雜度分析:
共 n 次更新、每次更新 O(log n)
Ruby@NTUIM

二元索引樹 > 運作方式

建構 Construction
Construction in linear time
\text{O}(n)
Credits @WilliamFiset
Ruby@NTUIM

運作方式

二元索引樹

內容大綱

Ruby@NTUIM

實際應用

運作方式

運作原理

程式實作

二元索引樹

Ruby@NTUIM

運作原理

二元索引樹

Ruby@NTUIM

二元索引樹 > 運作原理

16 10000
15 01111
14 01110
13 01101
12 01100
11 01011
10 01010
 9 01001
 8 01000
 7 00111
 6 00110
 5 00101
 4 00100
 3 00011
 2 00010
 1 00001
前綴和查詢 Prefix Sum Quries
1. 節點編號 Least Significant Bit
     = 該節點負責區間之長度
2. 負責區間從自己本身往下數
Ruby@NTUIM

二元索引樹 > 運作原理

16 10000
15 01111
14 01110
13 01101
12 01100
11 01011
10 01010
 9 01001
 8 01000
 7 00111
 6 00110
 5 00101
 4 00100
 3 00011
 2 00010
 1 00001
單點修改 Point Updates
Ruby@NTUIM

運作原理

二元索引樹

內容大綱

Ruby@NTUIM

實際應用

運作方式

運作原理

程式實作

二元索引樹

Ruby@NTUIM

程式實作

二元索引樹

Ruby@NTUIM

二元索引樹 > 程式實作

儲存方式 Array-based
N = 16
BIT = [ 0 ] * N
因此,BIT 很適合以「陣列」形式儲存
觀察:
一個基長度為 N 之陣列所建構的 BIT 必恰有 N 個節點,
且母節點與子節點之間編號關係明確。
Pseudo Code:
Ruby@NTUIM

二元索引樹 > 程式實作

前綴和查詢 Prefix Sum Quries
def query(i):
    sum = 0
    while i > 0:
        sum += BIT[i]
        i -= lsb(i)
    return sum
流程:
將索引值持續減去其本身的 Least Significant Bit,
並將所有經過節點權重相加,直到索引值被減至 0 為止。
Pseudo Code:
Ruby@NTUIM

二元索引樹 > 程式實作

def update(i, delta):
    while i <= N:
        BIT[i] += delta
        i += lsb(i)
流程:
將索引值持續加上其本身的 Least Significant Bit,
並將所有經過節點更新,直到索引值被加至超過 N 為止。
Pseudo Code:
單點修改 Point Updates
Ruby@NTUIM

二元索引樹 > 程式實作

def lsb(x):
    return x & -x
觀念:
要取得最小位元最簡單的方法是取 x 和 -x 的 bitwise and。
因為 -x 是 x 的補數 + 1 (Two's Complement)。

Pseudo Code:
二進制最小位元 Least Significant Bit
Ruby@NTUIM

二元索引樹 > 程式實作

完整範例程式碼 Example Code
Ruby@NTUIM

二元索引樹 > 程式實作

推薦資源 Recommended Resources
Ruby@NTUIM

程式實作

二元索引樹

內容大綱

Ruby@NTUIM

實際應用

運作方式

運作原理

程式實作

二元索引樹

謝謝大家

Brought to you by
顧寬証 B10705016
Ruby@NTUIM
Made with Slides.com