線段樹講解(資料結構 C )

2022-08-17 11:48:14 字數 2351 閱讀 9010

宣告    :

線段樹作為一種十分常用的資料結構,在noip、noi中廣泛的出現,所以在這裡對線段樹進行簡單的講解。

線段樹支援對乙個數列的求和、單點修改、求最值(最大、最小)、區間修改(需要lazy標記,暫不講解)。這幾種操作,時間複雜度是(logn)級別的,是一種十分優秀的資料結構。因此其獲得了廣泛的應用。

定義:顧名思義,它是一種樹形結構,但每段不是平常所學的乙個點乙個點的樹,而是一條一條的線段,每條線段包含著一些值,其中最主要的是起始和結束點記作 l,r 即左端點和右端點。

那麼該如何劃分線段樹呢?我們採用二分的思想,即每次將一段取半,再進行接下來的操作,這樣綜合了操作的方便程度和時間複雜度。因為線段樹通過二分得來,所以線段樹是一顆二叉樹。這也方便了對兒子查詢。下面是線段樹的圖,有利於理解:

建樹:僅僅知道模型還是不夠的,建樹的過程是線段樹的關鍵(build(1,1,n))從一號開始,左端是1,右端是n

位運算 i<<1 等效於 i/2  (i<<1)|1 等效於  i/2+1  加速。。。     

inline void update(int

i)更新i節點維護的值(求和,最大……)

inline

void build(int i,int l,int r)//

inline 還是加速

int mid=(l+r)/2;//

因為是二叉樹所以以中點為分割點

build(i<<1,l,mid);//

根據二叉樹的知識,左兒子是i/2右兒子是i/2+1

build((i<<1)|1,mid+1

,r);

update(i);

}

數列求和:這是線段樹的乙個典型演算法,其他的很多應用都是從中轉化的。

為了求和我們定義乙個函式sum(inti,intl,intr)i是開始的樹節點,我們預設為1。l是區間的開始點,它的標號是在數列中的標號,r是結束點其餘同l。帖下**:

inline int sum(int i,int l,int r)//

inline 又是加速

區間求最值和區間求和大致相同,自己看一下

inline int max(int i,int l,int

r)

單點更新:和區間不同,但基本思想還是一樣的。

inline void add(int i,int k,int v)//

當前計算到的點為i,把數列中的第k個元素加v

int mid=(node[i].l+node[i].r)/2

;

if(k<=mid) add(i<<1,k,v);//

若k小於mid則k在樹節點i的左子樹中

else add((i<<1)|1,k,v);//

反之 update(i);//

更新}

最後貼下全部的**基本可以做模板了。。

#include#include

using

namespace

std;

struct

tree;

tree node[

100];

int n,m,a[100

];inline

void update(int

i)inline

void build(int i,int l,intr)

int mid=(l+r)/2

; build(i

<<1

,l,mid);

build((i

<<1)|1,mid+1

,r);

update(i);

}inline

void add(int i,int k,int

v)

int mid=(node[i].l+node[i].r)/2

;

if(k<=mid) add(i<<1

,k,v);

else add((i<<1)|1

,k,v);

update(i);

}inline

int sum(int i,int l,int

r)inline

int max(int i,int l,int

r)int

main()

}

C 線段樹 高階資料結構

線段樹是一種平衡二叉搜尋樹 完全二叉樹 它將乙個線段區間劃分成一些單元區間。對於線段樹中的每乙個非葉子節點 a,b 他的左兒子表示的區間為 a,a b 2 右兒子表示的區間為 a b 2 1,b 最後的葉子節點數目為n,與陣列下標對應。線段樹的一般包括建立 查詢 插入 更新等操作,建立規模為n的時間...

Foreign 資料結構C 線段樹

首先,d操作為刪除操作顯然不可做,又發現這道題可以離線處理,那麼我們考慮倒著來,維護加入操作。那麼這時候,d操作就變為了合併操作,那麼這時候我們只需要維護乙個 可以支援單點修改 查詢第 k 大 資訊可合併的資料結構即可。顯然構建若干棵權值線段樹即可!對於每個聯通塊維護一棵線段樹,用並查集判斷兩點是否...

資料結構 線段樹

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