線段樹是acm中比較常見的資料結構,它的每一點都代表了一條線段[a,b],長度為1的為元線段,所有葉子結點的長度均為1。長度範圍為[1,l]的一顆線段樹的深度為log(l-1)+1。
線段樹基本的應用時查詢某段的和,最大最小值,成段更新,保證每次操作的複雜度為log(n)。
關於線段樹的文章有很多,大家可以參考
在這裡,我用hdu和poj上面的一些關於線段樹的簡單應用做為例題講解。
hdu1166(單點更新,區間求和):
敵軍海岸線上排列有n個營地,每個營地有若干個士兵,每個營地的士兵都是在隨時變動(增加或減少),要隨時求出任意兩個營地之間的士兵人數之和。
首先構造線段樹的結構:
struct seg_tree
}tt[max*4];//max是營地個數,一般線段樹的結點為它的4倍
然後就是建立線段樹:
int build(int left,int right,int idx)//idx從1開始
對於某個營地增加或減少士兵,有更新操作:
void update(int id,int x,int idx)
查詢某段營地士兵數量總和:
int query(int left,int right,int idx)
hdu1754(單點更新,區間最值):
老師喜歡問學生a到學生b中最好的成績是多少,其間,還會更改某些學生的成績。
建立線段樹:
int bulid(int left, int right, int idx)
對於某個學生成績的更改,有更新操作:
void update(int id, int value, int idx) //更新點,同時更新區間最值:先更新左右子樹的最值,然後更新父節點
int mid = tt[idx].calmid();
if(id <= mid)
update(id,value,ll(idx));
else
update(id,value,rr(idx));
tt[idx].value = max(tt[ll(idx)].value, tt[rr(idx)].value);
}
查詢某段學生成績中的最大值:
int query(int left, int right, int idx)
以上兩道例題是對於單點更新,對於成段更新,有hdu1698:
dota裡面有一種鉤子,它由n段組成,剛開始全部是銅的,每段重量為1。現在要把其中a-b這段換成金的或者銀的(重量分別為3,2),查詢這個鉤子的總重量。
建立線段樹:
void build(int left, int right, int idx)
更新a-b段的鉤子:
void update(int left, int right, int value, int idx) //更新區間
if(tt[idx].value != -1)
int mid = tt[idx].calmid();
if(left <= mid)
update(left,right,value,ll(idx));
if(mid < right)
update(left,right,value,rr(idx));
}
查詢某段鉤子的重量:
int query(int left, int right, int idx)
} int mid = tt[idx].calmid();
if(right <= mid)
return query(left,right,ll(idx));
else if(left > mid)
return query(left,right,rr(idx));
else
return query(left,mid,ll(idx)) + query(mid+1,right,rr(idx));
}
學習線段樹,要熟悉線段樹的構造,查詢,更新操作。 資料結構之線段樹
線段樹也叫區間樹,顧名思義,線段樹是一種基於區間的樹,每個節點表示乙個 線段 或 區間 樹的根節點表示是 整體 的區間,左右子樹分別表示這個區間的左半邊和右半邊。function 以節點v為根建樹 v對應區間為 l,r 線段樹的關鍵在於如何定義樹節點,以及如果構建 插入 樹節點。1.樹節點的定義 p...
資料結構之線段樹
一 引例 有m個數排成一列,做n次操作,每次操作包括 1 詢問指定區間的最大值 最小值 2 將指定區間的每個數加上乙個值 如果按照最樸素的做法,乙個個的遍歷,時間複雜度 o mn 那麼如何解決乙個區間求和 最大值,最小值 的問題呢?那麼就要用到線段樹啦。二 定義 線段樹是一種二叉搜尋樹,與區間樹相似...
資料結構之線段樹
線段樹是一種二叉查詢樹,它將乙個區間劃分為1個個單元,樹的每個節點都是1個單元。如下圖的樹就是一顆區間樹。性質 對於線段樹中的每乙個非葉子節點 a,b 它的左節點為 a,a b 2 右節點為 a b 2 1,b 線段數是平衡二叉樹,子節點的個數等於整個區間的長度。建樹 在這裡,我們使用陣列來實現簡單...