線段樹合併複雜度證明
阿新 • • 發佈:2018-12-06
前言
近期對線段樹合併有了更深的瞭解,所以在這裡寫一下一些自己的想法
適用問題
線段樹合併有一類經典的模板,現在對於一棵有n個葉子節點的樹(Tip:對於一棵N個節點的樹,其葉子節點數量小於等於 ),每個葉子節點上都有一個值域為m的值線上段樹中,一個非葉子節點節點的線段樹由所有子節點的線段樹合併而成,求相關的資訊
程式碼
inline node*merge(node*x,node*y)//node為線段樹節點的結構體名稱
{
if(x==NULL)return y;//NULL說明該指標為空
if(y==NULL)return x;
x->lson=merge(x->lson,y->lson);
x->rson=merge(x->rson,y->rson);
return x;
}
複雜度
對於整棵樹,做完的複雜度為
證明:
由於要遍歷整棵樹,所以有至少的O(N)的複雜度
對於一個葉子節點,其構樹的複雜度為
。容易發現,兩棵線段樹合併時,由於如果一棵線段樹為空就不做,只有兩顆線段樹都有值時往下,所以往下dfs的終止節點一定是兩棵線段樹節點的lca。對於一個節點,做完其子樹的線段樹合併的複雜度為
(Tip:由於對於兩條路徑可能會有相交之處,所以這個複雜度是上界,實際上這部分是不滿的)
每有一個滿足條件的lca,說明有兩個值合併在一起了,合併次數為N-1次,而深度是
的,所以總複雜度為O(nlogm+N)
證畢
例題
總結
這是一個很妙的模型,乍一眼複雜度不容易得出,而且比較好寫,值得記住