1、 線段樹是二叉樹,且必定是平衡二叉樹,但不一定是完全二叉樹。
2、 對於區間[a,b],令mid=(a+b)/2,則其左子樹為[a,mid],右子樹為[mid+1,b],當a==b時,該區間為線段樹的葉子,無需繼續往下划分。
3、 線段樹雖然不是完全二叉樹,但是可以用完全二叉樹的方式去構造並存儲它,只是最后一層可能存在某些葉子與葉子之間出現“空葉子”,這個無需理會,同樣給空葉子按順序編號,在遍歷線段樹時當判斷到a==b時就認為到了葉子,“空葉子”永遠也不會遍歷到。
4、 之所以要用完全二叉樹的方式去存儲線段樹,是為了提高在插入線段和搜索時的效率。用p*2,p*2+1的索引方式檢索p的左右子樹要比指針快得多。
5、線段樹的精髓是,能不往下搜索,就不要往下搜索,盡可能利用子樹的根的信息去獲取整棵子樹的信息。如果在插入線段或檢索特征值時,每次都非要搜索到葉子,還不如直接建一棵普通樹更來得方便。
但是這題單純用線段樹去求解一樣不會AC,原因是建立一棵[1,1QW]的線段樹,其根系是非常龐大的,TLE和MLE是鐵定的了。所以必須離散化。
通俗點說,離散化就是壓縮區間,使原有的長區間映射到新的短區間,但是區間壓縮前后的覆蓋關系不變。舉個例子:
有一條1到10的數軸(長度為9),給定4個區間[2,4] [3,6] [8,10] [6,9],覆蓋關系就是后者覆蓋前者,每個區間染色依次為 1 2 3 4。
現在我們抽取這4個區間的8個端點,2 4 3 6 8 10 6 9
然后刪除相同的端點,這里相同的端點為6,則剩下2 4 3 6 8 10 9
對其升序排序,得2 3 4 6 8 9 10
然后建立映射
2 3 4 6 8 9 10
↓ ↓ ↓ ↓ ↓ ↓ ↓
1 2 3 4 5 6 7
那么新的4個區間為 [1,3] [2,4] [5,7] [4,6],覆蓋關系沒有被改變。新數軸為1到7,即原數軸的長度從9壓縮到6,顯然構造[1,7]的線段樹比構造[1,10]的線段樹更省空間,搜索也更快,但是求解的結果卻是一致的。
離散化時有一點必須要注意的,就是必須先剔除相同端點后再排序,這樣可以減少參與排序元素的個數,節省時間。