以下**為樹狀陣列最常用的幾個操作
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
i:=x;
interim[x]:=y;
while i<=n do
begin
tree[i]:=y;
i:=i+lowbit(i);
end;
end;
3. 區間查詢
function get_summation(x:longint):int64;
var i:int64;
begin
get_summation:=0;
i:=x;
while i>0 do
begin
get_summation:=get_summation+tree[i];
i:=i-lowbit(i);
end;
exit(get_summation);
end;
4.區間極值
function get_maximum(x,y:int64):int64;
var i:int64;
begin
get_maximum:=0;
i:=y;
while i>=x do
begin
get_maximum:=max(interim[i],get_maximum);
i:=i-1;
while i-lowbit(i)>=x do
begin
get_maximum:=max(tree[i],get_maximum);
i:=i-lowbit(i);
end;
end;
exit(get_maximum);
end;
以及……
區間修改可以樹上差分。
樹狀陣列與線段樹相似,效率上要比線段樹高,但適用性卻不如線段樹。定義乙個陣列tre
etree
tree
表示子樹的葉子結點的權值之和,這樣可以發現到:
t re
e1=a
1tree_1 = a_1
tree1
=a1
t re
e2=a
1+a2
tree_2 = a_1 + a_2
tree2
=a1
+a2
t re
e3=a
3tree_3 = a_3
tree3
=a3
t re
e4=a
1+a2
+a3+
a4
tree_4 = a_1 + a_2 + a_3 + a_4
tree4
=a1
+a2
+a3
+a4
t re
e5=a
5tree_5 = a_5
tree5
=a5
t re
e6=a
5+a6
tree_6 = a_5 + a_6
tree6
=a5
+a6
t re
e7=a
7tree_7 = a_7
tree7
=a7
t re
e8=a
1+a2
+a3+
a4+a
5+a6
+a7+
a8
tree_8 = a_1 + a_2 + a_3 + a_4 + a_5 + a_6 + a_7 + a_8
tree8
=a1
+a2
+a3
+a4
+a5
+a6
+a7
+a8
⋯
\cdots
⋯ 經過觀察可以得出tre
ei=a
i−2k
+1+a
i−2k
+2+⋯
+a
itree_i = a_ + a_ + \cdots + a_i
treei
=ai−
2k+1
+ai
−2k+
2+⋯
+ai
l ow
bi
t\mathrm
lowbit
函式的意義是取為 x
xx 的二進位制表示式中最低位的1所對應的值
樹狀陣列本就是對於二進位制的理解&運用,利用 low
bi
t\mathrm
lowbit
我們可以快速遍歷整棵樹。
於是乎,樹狀陣列還可以解決各種關於區間の問題。
樹狀陣列學習筆記
在學習完了線段樹後,聽說樹狀陣列能寫的題,線段樹都能做,所以一直沒有詳細的學習樹狀陣列 直到碰到了一道卡線段樹的題目,因為線段樹運用了很多遞迴,所以常數比較大,容易被卡 現在總結一下樹狀陣列 1 樹狀陣列個人認為就是字首和演變而來的 2 單點更新 當你要更新某個點的值時,你要從下面到上面依次更新過去...
樹狀陣列學習筆記
樹狀陣列 binary index tree,bit 也是很多人心中最簡潔優美的資料結構之一。最簡單的樹狀陣列支援兩種操作,時間複雜度均為 當然,樹狀陣列能維護的不侷限於加法,支援的操作也不止這兩種,甚至有大佬能用樹狀陣列實現平衡樹,但這篇筆記不會深入討論 因為我也還不是很懂 回顧一下,我們說,我們...
樹狀陣列學習筆記
參考自 0.介紹 來自wikipedia 樹狀陣列,又稱二分索引樹 binary indexed tree,bit 用於高效計算數列的字首和.它可以以 的時間得到 並同樣以 對某項加乙個常數。1.資料結構定義 存放原始資料元素的陣列a i.e.int a 樹狀陣列 s i.e.int s 注意 原始...