學習筆記 樹狀陣列

2022-09-20 12:06:13 字數 1562 閱讀 4774

相信來到這裡的 \(oier\) 們,

都已經知道字首和是什麼了(不知道也不關我的事。

字首和可以支援 \(o(n)\) 級別的預處理以及 \(o(1)\) 級別的查詢區間和。

字首和的修改時間複雜度,卻是 \(o(n)\) 級別,

這是它最大的短板。

而我們今天要介紹的樹狀陣列,雖然只能做到 \(o(\log n)\) 級別的查詢,

但是相較字首和,

它的單點修改時間複雜度,能達到優秀的 \(o(\log n)\)

樹狀陣列有乙個最為核心的操作

\(lowbit\)。

顧名思義,\(lowbit\) 操作求的是十進位制數 \(x_\) 的二進位制狀態 \(x_\) 的最低位

而這種操作非常簡單,只需要一行**:

inline int lowbit(x)

舉個栗子:

\(x_=10,x_=1010\),

則\(-x_=-10,-x_=10110\)。

我們知道,負數是用補碼儲存的,所以有:

-x~x+1相等

於是 \(-x_\) 與 \(x_\) 的最低位仍然相等

接著,我們就可以開始建樹。

這是乙個典型的樹狀陣列,可以發現,

圖中 \(c_x\) 所管理的元素個數,正是 \(lowbit(x)\),

因此,有以下程式:

inline int lowbit(int x)

inline void update(int x,int k) //單點修改

}int main()

return 0;

}

說得通俗一點,

建樹操作,就是對乙個所有值為 \(0\) 的樹狀陣列進行 \(n\) 次單點修改

時間複雜度為 \(o(n\log n)\)。

樹狀陣列的求和操作,

本質上是對 \(1\sim x\) 的求和操作,

其實還是字首和的思想,

只不過,

樹狀陣列對區間進行劃分,每一段區間的和已經確定,

由此就可以做到 \(o(\log n)\) 級別查詢。

inline int lowbit(int x)

inline int query(int x)

return res;

}

樹狀陣列相對於我們之後要學習的線段樹相比,樹狀陣列的**比線段樹更短,思維更清晰,速度也更快,在解決一些單點修改的問題時,樹狀陣列是不二之選

學習筆記 樹狀陣列

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