數(shù)據(jù)類型·樹狀數(shù)組
CSDN博客鏈接:http://t.csdn.cn/f4OaS
樹狀數(shù)組問題
樹狀數(shù)組一般用于解決:給定一個數(shù)組,修改其中某些元素的值,求該數(shù)組某個區(qū)間的和的問題。如果我們用暴力方法來解決,那么每次查詢的時間復(fù)雜度都是 ??,以這種方法一旦數(shù)值過大,就會時間超限。于是我們就要用到樹狀數(shù)組的思路,它每次查詢的時間復(fù)雜度就是
,這樣就可以解決數(shù)值比較大的問題了。
那么我們來看一道模板例題:https://www.luogu.com.cn/problem/P3374,題干如下:
題目描述
如題,已知一個數(shù)列,你需要進(jìn)行下面兩種操作:
將某一個數(shù)加上
求出某區(qū)間每一個數(shù)的和
輸入格式
第一行包含兩個正整數(shù) ,分別表示該數(shù)列數(shù)字的個數(shù)和操作的總個數(shù)。??
第二行包含 個用空格分隔的整數(shù),其中第
個數(shù)字表示數(shù)列第
項(xiàng)的初始值。
接下來 行每行包含
個整數(shù),表示一個操作,具體如下:
1 x k ?含義:將第
個數(shù)加上
2 x y? 含義:輸出區(qū)間
內(nèi)每個數(shù)的和
輸出格式
輸出包含若干行整數(shù),即為所有操作 的結(jié)果。
樣例 #1
樣例輸入 #1
樣例輸出 #1
提示
【數(shù)據(jù)范圍】
對于 的數(shù)據(jù),
,
; ?
對于 的數(shù)據(jù),
; ?
對于 ?的數(shù)據(jù),
。
數(shù)據(jù)保證對于任意時刻, 的任意子區(qū)間(包括長度為
和
的子區(qū)間)和均在
?范圍內(nèi)。
樣例說明:

故輸出結(jié)果14、16
解決方法
?I ?暴力(70 pts)
當(dāng)然,我們也可以用前綴和的方法使查詢的時間復(fù)雜度降到 $O(1)$ ,但是對于每次修改數(shù)組中的數(shù)據(jù),復(fù)雜度就會變高,所以說整體的時間復(fù)雜度基本沒有變化。
II 樹狀數(shù)組
樹狀數(shù)組的本質(zhì)還是一個數(shù)組,但是我們可以用以下方法將其看作一個二叉樹,數(shù)組 $a$ 指的就是原數(shù)組, 指的是樹狀數(shù)組:

這個時候我們要用到 函數(shù)來計算
的值:
也可以這樣寫:
然后得出區(qū)間和:
向樹狀數(shù)組中添加元素:
這樣我們就寫好了樹狀數(shù)組的模板。
完整代碼如下:
總結(jié)
樹狀數(shù)組利用二進(jìn)制更新數(shù)組,將時間復(fù)雜度降低到 $O(log n)$
樹狀數(shù)組每個節(jié)點(diǎn)的值就是它的前綴和