**:
線段樹(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]
紅色的區間為完全重合的區間,因為在這個具體問題中我們只需要比較這 三個區間的值 找出 最大值 即可。
1int 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 因此線段樹是平衡二叉樹,最後的子節點數目為...