資料結構之線段樹

2021-06-18 01:02:52 字數 1822 閱讀 4707

線段樹也叫區間樹,顧名思義,線段樹是一種基於區間的樹,每個節點表示乙個「線段」或「區間」。樹的根節點表示是「整體」的區間,左右子樹分別表示這個區間的左半邊和右半邊。

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上,然後...