線段樹(陣列實現)

2022-08-19 18:51:23 字數 1076 閱讀 2117

最近看了很多學長髮的資料,吸取了別人的優點,把query函式更改的更加合理了。

—————————————————————我是分割線———————————————————————————————————————————— 

線段樹是一棵完美二叉樹,樹上的每個節點都維護乙個區間。根維護的是整個區間,每個節點維護的是父親的區間二等分後的其中乙個子區間。當有n個元素時,對區間的操作可以在o(logn)的時間內完成。

所以,線段樹是擅長處理區間的!

從網上找了乙個圖:

rmq(range minimum query)問題:

在給定數列a0,a1...an,給定s和t,線段樹可以求as...at的最值,以求最小值為例,如下圖:

每個節點維護對應區間的最小值,例如根節點維護的是下標1到8的最小值,左子樹維護的是1到4,右子書維護的是5到6,以此類推。

建樹時,父節點取左右子節點的較小者。我比較喜歡用陣列建樹,因為非常簡單清晰,下面是初始化線段樹的**:

1

#define max 999999999

2int k,n,tree[10005];//

n這裡是數列裡數字的個數

3void

init()

n小於k時,樹最後一層的其他值已經是max,所以不影響父節點,下面是線段樹每插入乙個值的更新:

1

void update(int pos,int val)

8 }

下面比較關鍵的是給定下標區間查詢,我會在注釋裡說明:

1

//呼叫時query(輸入a,輸入b,1,1,k)

2int query(int a,int b,int pos,int l,int r)

ok,到這裡,基本的演算法就實現了,注意一下樹的大小一定要合適。第一篇部落格,有些地方想講清楚可能講的還不透徹,等我的理解更加深入之後,會繼續修改的,如果有錯誤,希望大家指正,我會虛心接受的~

線段樹模板(陣列實現)

首先是基本定義環節 因為線段樹左子節點和右子節點在建構函式的時候比較常用 我們就把這兩個語句簡化一下 define lson l,m,rt 1 define rson m 1,r,rt 1 1 const int maxn 5008 int num maxn 2 之後就是乙個更新函式 常用於線段樹某...

陣列 線段樹

考慮所有右端點確定為位置 r 的區間,顯然它們的左端點取值可以在某個區間 l,r 中 因此我們只需要對每個 r 確定對應的 l 我們令 pre i 表示 i 位置前面第乙個和 i 顏色一樣的位置 那麼 l max pre i 1 也就是不能有同時2個出現在區間內 我們列舉 r 1 cdots n 得...

線段樹,樹狀陣列,主席樹

樹狀陣列 主席樹 包括無修改和可修改。用乙個滿二叉樹 葉子節點可以為空 來維護乙個連續陣列,整個樹的所有葉子節點從左到右表示整個陣列,每個非葉子節點表示其所有葉子的集合所描述的乙個連續子陣列的某一特性 最小值,最大值等 可以在logn的複雜度內實現對任意連續欄位的給定特性的查詢 最小值等 可以在lo...