C 線段樹 高階資料結構

2021-10-23 01:49:15 字數 3941 閱讀 2535

線段樹是一種平衡二叉搜尋樹(完全二叉樹),它將乙個線段區間劃分成一些單元區間。對於線段樹中的每乙個非葉子節點[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 大 資訊可合併的資料結構即可。顯然構建若干棵權值線段樹即可!對於每個聯通塊維護一棵線段樹,用並查集判斷兩點是否...

資料結構 線段樹

啦啦啦啦啦啦線段樹是個好東西 好吧並沒有什麼好的 但貌似還是很好啊 線段樹就是一棵樹!顧名思義 又是這個詞 就是求關於一段的某些什麼什麼東西。比如區間最大值啊什麼的。引用百科知識 線段樹是一種二叉搜尋樹,與區間樹相似,它將乙個區間劃分成一些單元區間,每個單元區間對應線段樹中的乙個葉結點。對於線段樹中...