線段樹也叫區間樹,顧名思義,線段樹是一種基於區間的樹,每個節點表示乙個「線段」或「區間」。樹的根節點表示是「整體」的區間,左右子樹分別表示這個區間的左半邊和右半邊。
function 以節點v為根建樹、v對應區間為[l,r]
}線段樹的關鍵在於如何定義樹節點,以及如果構建(插入)樹節點。
1.樹節點的定義
poj 3264 balanced lineup
給定q (1 ≤ q ≤ 200,000)個數a1,a2 … aq,,多次求任一區間ai – aj中最大數和最小數的差。
本題樹節點結構:
struct cnode;
poj 3468 a ****** problem with integers
給定q (1 ≤ q ≤ 100,000)個數a1,a2 … aq,,以及可能多次進行的兩個操作:
1) 對某個區間ai … aj的個數都加n(n可變)
2) 求某個區間ai … aj的數的和
本題樹節點結構:
struct cnode
; //本節點區間的和實際上是nsum+inc*(r-l+1)
poj 2528 mayor's posters
給定一些海報,可能互相重疊,告訴你每個海報寬度(高度都一樣)和先後疊放次序,問沒有被完全蓋住的海報有多少張。
struct cnode
; bcovered表示本區間是否已經完全被海報蓋住
關鍵: 插入資料的順序 ------ 從底至上依次插入每張海報
2.插入過程(構建)
以下是關於區間覆蓋問題的程式描述:
#include
using namespace std;
/* 線段樹求線段覆蓋長度 */
#define border 100 // 設線段端點座標不超過100
struct node // 線段樹
segtree[4*border];
/* 構建線段樹 根節點開始構建區間[lef,rig]的線段樹*/
void construct(int index, int lef, int rig)
int mid = (lef+rig) >> 1;
construct((index<<1)+1, lef, mid);
construct((index<<1)+2, mid, rig); // 非mid+1,線段覆蓋[mid,mid+1]
segtree[index].iscover = 0;
}/* 插入線段[start,end]到線段樹, 同時標記覆蓋 */
void insert(int index, int start, int end)
int mid = (segtree[index].left + segtree[index].right) >> 1;
if(end <= mid)
else if(start >= mid) // 勿漏=
else
}/* 計算線段覆蓋長度 */
int count(int index)
else if(segtree[index].right - segtree[index].left == 1)
return count((index<<1)+1) + count((index<<1)+2);
}/* 測試線段 answer: 71 */
int segment[10][2] = ;
void main()
printf("the cover length is %d\n", count(0));
}
資料結構之線段樹
一 引例 有m個數排成一列,做n次操作,每次操作包括 1 詢問指定區間的最大值 最小值 2 將指定區間的每個數加上乙個值 如果按照最樸素的做法,乙個個的遍歷,時間複雜度 o mn 那麼如何解決乙個區間求和 最大值,最小值 的問題呢?那麼就要用到線段樹啦。二 定義 線段樹是一種二叉搜尋樹,與區間樹相似...
資料結構之線段樹
線段樹是一種二叉查詢樹,它將乙個區間劃分為1個個單元,樹的每個節點都是1個單元。如下圖的樹就是一顆區間樹。性質 對於線段樹中的每乙個非葉子節點 a,b 它的左節點為 a,a b 2 右節點為 a b 2 1,b 線段數是平衡二叉樹,子節點的個數等於整個區間的長度。建樹 在這裡,我們使用陣列來實現簡單...
關於資料結構之線段樹
這幾天都一直在看關於線段樹的題目還有題解,還有做題!以前也知道有線段樹這個東西,但是那時沒有好好的看,就看了個簡單的皮毛!所以現在又拿出來好好看看!一開始看,一直看題解,還有就是模仿,首先看一遍,初步了解一下,然後就是按著別人的題解再抄著寫一遍直到通過測試,當然不是直接對著乙個乙個的copy上,然後...