「樹狀數組」第 2 節:理解預處理數組 C

「樹狀數組」第 2 節:理解預處理數組 C

我們看看樹狀數組長什麼樣。

樹狀數組的樣子

在這裏插入圖片描述

例 5

我們以一個有 8 個元素的數組 A 爲例(如上圖),在數組 A 之上建立一個數組 C,使得數組 C 的形成如上的一個多叉樹形狀,數組 C 就形成了一個樹狀數組的結構。以下是兩點說明:

  • 樹狀數組要建成動態的樹形結構嗎?

    • 不用。學習過堆、線段樹的朋友一定知道,使用數組就能方便地索引左右孩子結點、雙親結點(因爲規律特別容易找到),這樣的樹就不必創建成結點、指針那樣的動態樹形結構。
  • 如何解釋「前綴和」查詢和「單點更新」操作?

    • 如果要查詢「前綴和(4)」,本來應該查 A1A2A3A4,然後把它們相加;
    • 有了數組 C 之後,我們只要問 C4 即可;
    • 我們要更新結點 A1 的值,只要自底向上更新 C1C2C4C8 的值即可。

我們構建好數組 C 以後,就完全可以拋棄數組 A 了。

理解數組 C 的定義

  • 首先我們強調一點,樹狀數組的下標從 11 開始,下標 00 號我們不用,這一點我們看到後面就會明白。我們先了解如下的定義,請大家一定先記住這些記號所代表的含義:

    • 數組 C 是一個對原始數組 A 的預處理數組。
  • 我們還要熟悉幾個記號。爲了方便說明,避免後面行文囉嗦,我們將固定使用記號 iijjkk,它們的定義如下:

    • 記號 ii :表示預處理數組 CC 的索引(十進制表示);
    • 記號 jj :表示原始數組 AA 的索引(十進制表示)。

我們通過以下的圖,來看看 C1C2C3C4C5C6C7C8 分別是如何定義的。

在這裏插入圖片描述
在這裏插入圖片描述

在這裏插入圖片描述
上面的過程我們用如下的表來表示。
在這裏插入圖片描述

數組 C 的下標與數組 A 的下標的關係

  • 偉大的計算機科學家注意到上表中標註了數組 C 中的元素來自數組 A 的元素個數,它們的規律如下:
    • 將數組 C 的下標 ii 表示成二進制,從右向左數,遇到 11 則停止,數出 00 的個數記爲 kk,則 2k2^k的值 就是「數組 C 中的元素來自數組 A 的個數」,並且可以具體得到來自數組 A 的表示,即從當前下標 ii 開始,從右向前數出 2k2^k 個數組 A 中的元素的和,即組成了 C[i]

下面具體說明。

  • 記號 kk :將 ii 的二進制表示從右向左數出的 00 的個數,遇到 11 則停止,記爲 kk。 我們只對數組 CC 的索引 ii 進行這個計算,數組 AA 的索引 jj 不進行相應的計算;
  • 這裏理解 kk 是如何得到的是重點。

下面我們通過兩個例子進行說明。

例 6

i=5i = 5 時,計算 kk

  • 分析:因爲 55 的二進制表示是 0000  01010000\;0101,從右邊向左邊數,第 11 個是 11 ,因此 00 的個數是 00,此時 k=0k=0

例 7

i=8i = 8 時,計算 kk

分析:因爲 88 的二進制表示是 0000  10000000\;1000,從右邊向左邊數遇到 11 之前,遇到了 3300,此時 kk = 3。 計算出 kk 以後,2k2^k 立馬得到,爲此我們可以畫出如下表格:

在這裏插入圖片描述

我們看到 2k2^k 是我們最終想要的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章