線段樹學習筆記

2021-07-10 10:30:19 字數 2115 閱讀 2237

本文筆記在參考一步一步理解線段樹-tenos的基礎上形成

線段樹,也是二叉搜尋樹的一種,是基於陣列,但是優於陣列的一種資料結構。同時結合預處理(時間複雜度一般在o(n))使得從原來陣列的o(n)的查詢和更新複雜度降到了o(logn),在處理很大資料量的資料更新和查詢最值方面變得簡單,值得一提的是,它的構建也很簡單。這裡從最小值的問題討論(一般,線段樹用在查詢最值比較方便)

1.構建線段樹:

構建的思想是從根節點開始,逐步接近葉子節點,這裡採用基於陣列的方式構建線段樹。

樹的編號是從上大下,從左到右依次增大的,管理的區間長度隨著樹的層次增加而每次縮短。比如從根節點到葉子的管理的區間變化是:

[0, n) --> [0, n/2) & [n/2, n), -->......-->0, 1, 2, 3,....., n-1

所以構建線段樹(c++)的**如下:

#include #include using namespace std;

const int maxn = 1000;

const int inf = numeric_limits::max();

struct lineartree lt[maxn];

void construct(int root, int* arr, int l, int r)

}

2.線段樹查詢操作:

對於給定區間(區間最小長度為1,這裡統一都是採用左閉右開的方式),要查詢它的最小值,可以從根節點開始,不斷將要查詢的區間進行切割,從而得到查詢結果,主要是這樣:

1)對於當前訪問區段,如果該區段與查詢區段沒有交集,那麼返回乙個inf;

2)對於當前訪問區段,如果該區段包含在查詢區段裡,那麼當前訪問區段的最小值;

3)如果以上兩種情況都不是,那麼對當前區段二分,通過訪問其子區段,來查詢結果;

以上三種就是全部情況了,實際上第二種情況是第三種情況的子情況,同時對於之前所說的切割也是在這兩種情況之下進行的,比如在第二種就說明訪問區間是當前區間的子區間,第三種情況就可以把部分相交的訪問區間切割成第一和第二種情況,第一種情況可以略掉,第二種就變成它的子情況了,再通過這些子區間的比較就可以得到查詢結果:

int requir(int root, int cl, int cr, int ql, int qr)

3.線段樹更新:

更新分為兩種,一種是對單個元素更新,一種是對單個區間更新。我參考的那篇文章的作者設計了一套方法,可以方便更新,但是對於這種求最值的問題似乎沒有這個必要,如果是求和的話,或者說進行區間比較就很方便了(以下為advanced版本):

#include #include using namespace std;

const int maxn = 1000;

const int inf = numeric_limits::max();

struct lineartree lt[maxn];

void send(int root)

}void construct(int root, int* arr, int l, int r)

}int requir(int root, int cl, int cr, int ql, int qr)

void renewsing(int idx, int x, int root, int l, int r)

}viod renewseg(int root, int alter, int l, int r, int alterl, int alterr)

//將之前的更新值向下傳遞

send(root);

int mid = (l + r) / 2;

renewseg(root*2 + 1, alter, l, mid, alterl, alterr);

renewseg(root*2 + 2, alter, mid, r, alterl, alterr);

//回溯更新

lt[root] = min(lt[root*2 + 1], lt[root*2 + 2]);

}

線段樹學習筆記

線段樹是一種 二叉搜尋樹 與區間樹 相似,它將乙個區間劃分成一些單元區間,每個單元區間對應線段樹中的乙個葉結點。使用線段樹可以快速的查詢某乙個節點在若干條線段中出現的次數,時間複雜度為o logn 而未優化的 空間複雜度 為2n,因此有時需要離散化讓空間壓縮。以下筆記摘自lcomyn神犇部落格 1....

線段樹學習筆記

線段樹是一種維護區間的資料結構,且滿足二叉樹的全部性質 下圖是一棵維護區間 1 6 1,6 的線段樹 格式 idl ri dl r我們可以發現,對於每個節點 k k 來說,其左節點編號為2k role presentation style position relative 2k2 k,右節點編號為...

線段樹學習筆記

線段樹的構造 void build node cur,int l,int r else cur leftchild cur rightchild null 線段樹的查詢 int query node cur,int l,int r 線段樹的延遲修改 void change node cur,int ...