var sum int
var lazytint
var arrint
//改變了區間中某乙個值或某些值時,我們需要沿著線段樹向上更新改變值的節點與根節點間的所有值,可以看出這部操作與線段樹的高度有關,複雜度為o(logn)
func pushup(idx int)
//build
func build(left,right,idx int)
var mid=left+(right-left)/2
build(left,mid,idx*2)
build(mid+1,right,idx*2+1)
pushup(idx)
}//單點修改。改變區件中的某乙個值,即在樹中找到對應的葉節點,更新其值,然後遞迴改變該節點到根節點路徑上所有節點的值
func updatepoint(changedidx,changedvalue,left,right,idx int)
var mid=left+(right-left)/2
if changedidx<=midelse
pushup(idx)//子節點更新了,所以本節點也需要更新資訊
}//區間修改,在區間修改的時候我們引入乙個新的概念——懶惰標記
////懶惰標記:表示本節點的統計資訊已經根據標記更新過了,但是本節點的子節點還沒有更新
//func pushdown(idx,leftnum,righttree int)
}func updateseg(changedleftidx,changedrightidx, changedvalue, left, right,idx int)
var mid=left+(right-left)/2
pushdown(idx,mid-left+1,right-mid)
if changedleftidx<=mid
if changedrightidx>mid
pushup(idx)//更新本節點資訊
}//查詢,查詢過程中有乙個很重要的操作便是懶惰標記的下推,理解了懶惰標記的下推,查詢操作就很好理解
func query(queryleft,queryright, left, right, idx int)int
var mid=left+(right-left)/2
pushdown(idx,mid-left+1,right-mid)
var res int
if queryleft<=mid
if queryright>mid
return res
}
參考:1,2 RMQ(線段樹實現)
t t第乙個線段樹程式,還沒a過題,不過也很感動,先貼出來 下標從0開始,輸入 1 1 結束.求每一段區間之間的最大值。include include typedef struct treenodenode int mymax int a,int b node buildtree int a,int...
線段樹簡單實現
首先,線段樹是一棵滿二叉樹。每個節點要麼有兩個孩子,要麼是深度相同的葉子節點 每個節點維護某個區間,根維護所有的。如圖,區間是二分父的區間。當有n個元素,初始化需要o n 時間,對區間操作需要o logn 時間。下面給出維護區間最小值的思路和 從下往上,每個節點的值為左右區間較小的那乙個即可。這算是...
線段樹(陣列實現)
最近看了很多學長髮的資料,吸取了別人的優點,把query函式更改的更加合理了。我是分割線 線段樹是一棵完美二叉樹,樹上的每個節點都維護乙個區間。根維護的是整個區間,每個節點維護的是父親的區間二等分後的其中乙個子區間。當有n個元素時,對區間的操作可以在o logn 的時間內完成。所以,線段樹是擅長處理...