線段樹入門整理

2022-05-15 22:03:57 字數 1637 閱讀 4997

**:

線段樹(interval tree) 是把區間逐次二分得到的一樹狀結構,它反映了包括歸併排序在內的很多分治演算法的問題求解方式。

【宣告】

1 #include2 #include3

const

int maxnode = 2097152;4

const

int max = 1000003;5

struct

nodenode[maxnode];

9int father[max]; //

每個點(當區間長度為0時,對應乙個點)對應的結構體陣列下標

【建立線段樹(初始化)】:

線段樹是用二叉樹結構儲存的,而且是完全二叉樹

在完全二叉樹中假如乙個結點的序號(陣列下標)為 n ,那麼 (二叉樹基本關係)

n的父親為 n/2,

n 的另乙個兄弟為 n/2*2 或 n/2*2+1

n 的兩個孩子為n*2 (左)   n*2+1(右)

根據這樣的關係,就可以很簡單明瞭的寫出建樹的**了

1

void buildtree(int i,int left,int right) //

為區間[left,right]建立乙個以結點i為祖先的線段樹,i又為為陣列下標,也是結點序號210

//該結點往 左孩子的方向 繼續建立線段樹

11//

這裡將 區間[left,right] 一分為二了

12 buildtree(i<<1, left, (right+left) / 2

));13

//該結點往 右孩子的方向 繼續建立線段樹

14 buildtree((i<<1)+1, (right+left) / 2 + 1

, right);

15 }

【單點更新線段樹】:

最初用father陣列儲存了每乙個單位區間長度的結點下標,因此就容易由下往上更新了

(此處以更新區間最大值為例)

1

void updatatree(int ri) //

從下往上更新(這個點本身已經在函式外面更新過了)

2

【查詢區間最大值】:

將一段區間按照建立的線段樹從上往下一直拆開,直到存在有完全重合的區間停止。對照圖例建立的樹,假如查詢區間為 [2,5]

紅色的區間為完全重合的區間,因為在這個具體問題中我們只需要比較這 三個區間的值 找出 最大值 即可。

1

int max = -1

<< 20;2

void query(int i,int l,intr)3

8 i = i << 1; //

查詢此結點的左孩子結點

9if(l <= node[i].right)

15 i+=1; //

右孩子結點

16if(r >= node[i].left)

22 }

線段樹入門 資料整理

c題題解,專題訓練一 講解線段樹從入門到高階 線段樹開闢的空間一般是需要儲存的資料的4倍。線段樹使用了二分的思想 我自己認為 把區域進行不斷的二分。她能把一些對於區間 或者線段 的修改 維護,從 o n 的時間複雜度變成 o logn 目前常見的模板中,大體有兩種形式 使用簡單陣列,在函式引數表表示...

線段樹入門

線段樹 interval tree 是把區間逐次二分得到的一樹狀結構,它反映了包括歸併排序在內的很多分治演算法的問題求解方式。上圖是一棵典型的線段樹,它對區間 1,10 進行分割,直到單個點。這棵樹的特點 是 1.每一層都是區間 a,b 的乙個劃分,記 l b a 2.一共有log2l層 3.給定乙...

線段樹入門

學習下 線段樹的入門級 總結 線段樹是一種二叉搜尋樹,與區間樹相似,它將乙個區間劃分成一些單元區間,每個單元區間對應線段樹中的乙個葉結點。對於線段樹中的每乙個非葉子節點 a,b 它的左兒子表示的區間為 a,a b 2 右兒子表示的區間為 a b 2 1,b 因此線段樹是平衡二叉樹,最後的子節點數目為...