資料結構 線段樹初步

2022-09-18 09:09:51 字數 2418 閱讀 8419

眾所周知,線段樹是oi當中十分重要的乙個資料結構,所以我們今天就來講一講這個線段樹。

首先,我們來了解一下什麼是線段樹。

給定乙個1~ n的區間,我們考慮,將這個區間進行二分,使得這個區

間下擁有兩個小區間,如此反覆操作,直至這個區間被二分的只剩下乙個點,

那麼這就是這棵線段樹的葉節點,線段樹的實質上是一顆二叉樹,但未必是

一顆完全二叉樹。

那麼,引入這樣的線段樹結構有什麼用呢?

我們可以發現,對於線段樹上的乙個結點,其父節點的資訊一定是它和它兄

弟的綜合,也就是說,我們查詢乙個區間內的資訊,就只需要遍歷到乙個(或

多個的綜合)代表著該區間的結點,就可以得

到我們想要的資訊,而不需要遍

歷線段上的每個點,顯然這樣的效率是會大大優化的,通過理論證明,我們可

以發現,對於一棵線段樹,他的每次操作的時間複雜度是o(qlog2(n))的,而它的最大空間複雜度可以近似看為o(4n),事實上可以證明,實際的空間複雜度約為o(大於等於2n的最小的2的整數次方)。這樣的空間複雜度是較高的,

因此我們常常使用離散化的方式降低線段樹的空間複雜度。

接下來我們講一下如何進行程式設計實現。

首先,我們考慮如何進行定點修改,顯然對於一次修改,我們可以直接通

過從整條線段上一直進行二分,找到它所對應的結點,再進行修改,之後

回溯修改它父親結點的資訊即可,這樣的效率顯然是o(log2(n))的。(標程略)

接下來我們來考慮如何查詢區間內的資訊,對於乙個區間,顯然要麼它恰

好是線段樹上的乙個區間,要麼它就是由多個相鄰區間拼湊而成,因此我們

同樣考慮進行遞迴回溯,使得這個區間內的所有子區間被查詢到且不重複,

進行合併處理的出最後答案,事實上這樣的效率也是o(log2(n))的。(附簡單標程,pushdown會在後文中提到:))

1 query(int l,int r,int a,int b,int t)
點此檢視查詢函式query

現在我們繼續進行拓展,要如何進行區間修改呢?

我們考慮如果僅僅是按照定點修改的方法進行處理,每次操作的複雜度

是o(nlog2(n)),這樣顯然是複雜度過高不可接受的。

考慮採用類似查詢的操作進行處理,這時出現了乙個問題,我們只能更

改到區間的值,如果這時我們查詢了這個區間的子區間的值,顯然這會導致

我們的解不是當前狀態下的解,

因此,我們考慮將區間更改的值進行延遲傳遞,這就是我們常常聽到的線段樹的lazy標記(我個人習慣稱之為mark)。

這裡的延遲傳遞是什麼概念呢?

我們可以這麼認為,在進行乙個操作時,只要我所遞迴到的區間的值是當前狀態即可,否則我就沒有更新的必要,因此,我們將每次要進行更新的值暫時存在乙個已經訪問到的區間,只有我遞迴到了它的子區間,我才需要進行值得更新傳遞,這也就是我們所說的lazy標記傳遞。(附上線段樹延遲標記傳遞的函式)

1

void pushdown(int t,int l,int r)

點此檢視延遲標記的傳輸函式pushdown

接下來,我們來看一下如何進行區間修改(附相關函式)

1 update(int a,int b,int l,int r,int t,int add_val)

8pushdown(t,a,b);

9int m=(a+b)/2;10

if (m>=l) update(a,m,l,r,t*2

,add_val);

11if (m1,b,l,r,t*2+1

,add_val);

12 tree[t].val=tree[t*2].val+tree[t*2+1

].val;

13 }

於是我們就講完了線段樹的一些基本操作了,撒花~~

資料結構 線段樹

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

資料結構 線段樹

一 目標 1.如何快速的查詢出下列陣列arr 2,5 的和 2。以及更新arr 4 為6。用普通的方法查詢的複雜度為o n 更新的複雜度為o 1 這時候我們可以用線段樹來快速完成這些操作,複雜度為logn。二 內容 如何建立,查詢,更新線段樹。public class qurqpd int tree...

資料結構 線段樹

線段樹是一顆平衡的二叉搜尋樹,他以空間換區時間,讓線性查詢加速log級別的查詢,用到的演算法主要是二分搜尋和遞迴。例如 有陣列data 我有乙個需求,我需要頻繁的查詢區間i j的sum和。這裡先給出兩個解決方案 如果使用最普通的演算法遍歷,那麼查詢和更新的複雜度為o n 當然你還可以使用動態規劃,定...