線段樹是一種平衡二叉搜尋樹(完全二叉樹),它將乙個線段區間劃分成一些單元區間。對於線段樹中的每乙個非葉子節點[a,b],他的左兒子表示的區間為[a,(a+b)/2],右兒子表示的區間為[(a+b)/2+1,b],最後的葉子節點數目為n,與陣列下標對應。線段樹的一般包括建立、查詢、插入、更新等操作,建立規模為n的時間複雜度是o(nlogn),其他操作時間複雜度為o(logn)。
平衡二叉搜尋樹(完全二叉樹)是指除了最後一層,其他層都是滿的二叉樹。
線段樹最大的價值是平衡,因為線段樹是平衡二叉樹。很多題目可以通過平衡二叉樹達到完美的時間複雜度。
#include
//線段樹的構造
void
build_segment_tree
(std::vector<
int>
& nums, std::vector<
int>
& value,
int pos,
int left,
int right)
int mid =
(left + right)/2
;build_segment_tree
(nums, value,
2* pos +
1, left, mid)
;build_segment_tree
(nums, value,
2* pos +
2, mid+
1, right)
; value[pos]
= value[
2* pos +1]
+ value[
2* pos +2]
;}//線段樹的遍歷
void
print_segment_tree
(std::vector<
int>
& value,
int pos,
int left,
int right,
int layer)
printf
("[%d %d] [%d]: %d\n"
, left, right, pos, value[pos]);
if(left==right)
int mid =
(left + right)/2
;print_segment_tree
(value,
2* pos +
1, left, mid, layer +1)
;print_segment_tree
(value,
2* pos +
2, mid +
1, right, layer +1)
;}//線段樹的求和
intsum_range_segment_tree
(std::vector<
int>
& value,
int pos,
int left,
int right,
int qleft,
int qright)
if(qleft<=left&&qright>=right)
int mid =
(left + right)/2
;return
sum_range_segment_tree
(value,
2* pos +
1, left, mid, qleft, qright)
+sum_range_segment_tree
(value,
2* pos +
2, mid +
1, right, qleft, qright);}
//線段樹的更新
void
update_segment_tree
(std::vector<
int>
& value,
int pos,
int left,
int right,
int index,
int new_value)
int mid =
(left + right)/2
;if(index<=mid)
else
value[pos]
= value[
2* pos +1]
+ value[
2* pos +2]
;}intmain()
std::vector<
int> value;
for(
int i =
0; i <
24; i++
)build_segment_tree
(nums, value,0,
0, nums.
size()
-1);
printf
("segment tree:\n");
print_segment_tree
(value,0,
0,nums.
size()
-1,0
);int sum_range =
sum_range_segment_tree
(value,0,
0, nums.
size()
-1,2
,4);
printf
("sum_range [2,5]=%d\n"
, sum_range)
;update_segment_tree
(value,0,
0, nums.
size()
-1,2
,10);
printf
("segment_tree:\n");
print_segment_tree
(value,0,
0,nums.
size()
-1,0
);return0;
}
執行結果為:
segment tree:[0
5][0
]:15---[
02][
1]:3
------[
01][
3]:1
----
-----[
00][
7]:0
----
-----[
11][
8]:1
------[
22][
4]:2
---[3
5][2
]:12--
----[3
4][5
]:7--
-------
[33]
[11]:
3---------
[44]
[12]:
4------[5
5][6
]:5sum_range [2,
5]=9
segment_tree:[0
5][0
]:23---[
02][
1]:11
------[
01][
3]:1
----
-----[
00][
7]:0
----
-----[
11][
8]:1
------[
22][
4]:10
---[3
5][2
]:12--
----[3
4][5
]:7--
-------
[33]
[11]:
3---------
[44]
[12]:
4------[5
5][6
]:5
高階資料結構 線段樹
今天是很沉重的一天,進來ccf官宣取消oi,也不知道是不是真的。oier們不要放棄夢想!大家一定要勇往直前!這線段樹會很難 至少我是這麼想的 不過我也是經過百般實驗才敢寫這個部落格!假定我給你乙個定區間,讓你以最快的速度做這樣的操作 修改其中的乙個子區間,查詢另乙個子區間的值,而且重複這些操作。你會...
Foreign 資料結構C 線段樹
首先,d操作為刪除操作顯然不可做,又發現這道題可以離線處理,那麼我們考慮倒著來,維護加入操作。那麼這時候,d操作就變為了合併操作,那麼這時候我們只需要維護乙個 可以支援單點修改 查詢第 k 大 資訊可合併的資料結構即可。顯然構建若干棵權值線段樹即可!對於每個聯通塊維護一棵線段樹,用並查集判斷兩點是否...
資料結構 線段樹
啦啦啦啦啦啦線段樹是個好東西 好吧並沒有什麼好的 但貌似還是很好啊 線段樹就是一棵樹!顧名思義 又是這個詞 就是求關於一段的某些什麼什麼東西。比如區間最大值啊什麼的。引用百科知識 線段樹是一種二叉搜尋樹,與區間樹相似,它將乙個區間劃分成一些單元區間,每個單元區間對應線段樹中的乙個葉結點。對於線段樹中...