資料結構 線段樹

2021-07-16 07:33:00 字數 1689 閱讀 2137

啦啦啦啦啦啦線段樹是個好東西- -

好吧並沒有什麼好的- -但貌似還是很好啊- -

線段樹就是一棵樹!

顧名思義(又是這個詞),就是求關於一段的某些什麼什麼東西。比如區間最大值啊什麼的。

引用百科知識:

線段樹是一種二叉搜尋樹,與區間樹相似,它將乙個區間劃分成一些單元區間,每個單元區間對應線段樹中的乙個葉結點。

對於線段樹中的每乙個非葉子節點[a,b],它的左兒子表示的區間為[a,(a+b)/2],右兒子表示的區間為[(a+b)/2+1,b]。因此線段樹是平衡二叉樹,最後的子節點數目為n,即整個線段區間的長度。

使用線段樹可以快速的查詢某乙個節點在若干條線段中出現的次數,時間複雜度為o(logn)。而未優化的空間複雜度為2n,因此有時需要離散化讓空間壓縮。

線段樹至少支援下列操作:

insert(t,x):將包含在區間 int 的元素 x 插入到樹t中;

delete(t,x):從線段樹 t 中刪除元素 x;

search(t,x):返回乙個指向樹 t 中元素 x 的指標。

恩就是這樣,我來畫個圖說明儲存的資料吧:

差不多是這個樣子的。

明顯的,假設我們建立一棵線段樹,它的時間複雜度的o(n),修改乙個或是查詢乙個都是o(nlogn)

為嘛?不為嘛!

怎麼求呢?拿修改來說,主要是運用遞迴的思想,一路往下找,找到要求的位置,修改值,再一路向上修改最大值什麼的。

而查詢乙個最大值呢?就是在找包含關係。

如有8個數,求第2到第7的最大值:

在1~8找2~7——>在1~4找2~7——>在1~2找2~7——>在2找2~7(發現2包含在2~7內,返回2的值)——>在3~4找2~7(發現3~4包含在2~7內,返回3~4的值)——>在5~8找2~7——>在5~6找2~7(······)——>在7~8找2~7——>在7找2~7

就是這樣(好累)。

在找的過程中發現,因為區間是連續的,所以一段要麼是完全被包含,要麼是分叉繼續找,而若是分叉部分完全被包含,則被包含的區域是連在一起的,不存在像【取了1~2、5~6而其他不去】的情況。

如上圖,黑色部分表示被包含。而我們可以看出,相對於左子樹,其被包含部分都在右邊;而相對於右子樹,其被包含部分都在左邊。

講了這麼多,程式就直接放上去吧(cxb)

#include using namespace std;

const int maxn =1000007;

const int oo = 0x0fffffff;

struct tnode

;tnode f[maxn];

int fp=0;

int root;

int getpoint(int l, int r, int max)

//存資料

int create(int l, int r)

//查詢一段的最大值

int n;

int q;

int main()

else

if (oper == 'i')//修改乙個值

}return 0;

}

資料結構 線段樹

一 目標 1.如何快速的查詢出下列陣列arr 2,5 的和 2。以及更新arr 4 為6。用普通的方法查詢的複雜度為o n 更新的複雜度為o 1 這時候我們可以用線段樹來快速完成這些操作,複雜度為logn。二 內容 如何建立,查詢,更新線段樹。public class qurqpd int tree...

資料結構 線段樹

線段樹是一顆平衡的二叉搜尋樹,他以空間換區時間,讓線性查詢加速log級別的查詢,用到的演算法主要是二分搜尋和遞迴。例如 有陣列data 我有乙個需求,我需要頻繁的查詢區間i j的sum和。這裡先給出兩個解決方案 如果使用最普通的演算法遍歷,那麼查詢和更新的複雜度為o n 當然你還可以使用動態規劃,定...

資料結構 線段樹

摘自 演算法競賽高階指南 線段樹是一種基於分治思想的二叉樹結構,用於在區間上進行資訊統計。線段樹的基本特徵 1.線段樹的每個節點都代表乙個區間。2.線段樹具有唯一的根節點,代表的區間是整個統計範圍,如 1,n 3.線段樹的每個葉節點都代表乙個長度為1的元區間 x,x 4.對於每個內部節點 l,r 它...