線段樹入門理解
這個連結上面對線段樹描述得很清楚【線段樹】線段樹入門之入門
下面談談自己的理解:
線段樹對多次查詢極有優勢,因為一般情況下並不需要掃描到樹的最底端就能得出結果。
個人感覺線段樹也是一種打表(樹形的表?)=。=比如哦,求區間的最大值,用線段樹的話,方法抽象點的說就是區間打表(個人猜測).....分別對每個區間記錄下其最大值,當掃描到這個區間的時候,直接取這個區間存放的最大值,避免再次深入搜尋。
線段樹更新的話,從根節點向父節點遞迴,凡是與節點數值變動有影響的節點,均需要更新一下以免出現父節點最大值並不等於所有子節點中最大值這種情況。但是與變動節點沒有影響的其餘節點,那麼則不需要改變。
貼上個人寫的程式碼(註釋寫得還是很清楚的....):
/*
線段樹入門
該例為查詢區間的最大值
*/
#include <iostream>
#include <cmath>
using namespace std;
const int MAXNODE = 2000006;
const int MAX = 1000003;
struct Node
{
int value;
int left, right;
};
Node node[MAXNODE];
int root[MAX]; //對線段樹的根節點進行打表,記錄下每個根節點所對應的樹的編號
void BuildTree(int i, int left, int right) //建立一棵樹,i代表起始點,l,r代表線段樹長度
{
node[i].left = left;
node[i].right = right;
node[i].value = 0;
if (left == right)
{
root[left] = i; //記錄葉子節點所對應的樹的序號
return;
}
BuildTree(i << 1, left, (int)((left + right) / 2));
BuildTree((i << 1) + 1, (int)((left + right) / 2) + 1, right);
}
void UpdateTree(int i) //從下到上更新節點,在函式外部更改根節點,i代表變動節點
{
if (i == 1)
return;
int x = i / 2; //樹節點標號向上更改
int a = node[x << 1].value; //記錄左子節點值
int b = node[(x << 1) + 1].value; //記錄右子節點值
node[x].value = (a > b)? a : b;
UpdateTree(x);
}
int Max = -1;
void Query(int i, int l, int r) //查詢節點,i代表查詢起始節點編號,l,r代表要查詢的線段區間
{
if (node[i].left == l && node[i].right == r) //找到匹配區間段,記錄下最大值並退出
{
Max = (Max < node[i].value)? node[i].value : Max;
return;
}
//如果不滿足整體匹配,那麼對查詢段進行拆分
i = i << 1; //首先進入左子樹查詢
if (l <= node[i].right) //如果滿足查詢段中存在從起點數一段屬於左子樹
{
if (r <= node[i].right) //如果查詢段全部屬於左子樹
Query(i, l, r); //遞迴進入左子樹再次查詢
else
Query(i, l, node[i].right); //否則部分進入左子樹查詢
}
i += 1; //接下來查詢右子樹
if (r >= node[i].left)
{
if (l >= node[i].left) //如果全部屬於右子樹那麼遞迴進入右子樹繼續查詢
Query(i, l, r);
else
Query(i, node[i].left, r); //否則屬於右子樹的線段遞迴右子樹查詢
}
}
int main()
{
BuildTree(1, 1, 5);
node[root[1]].value = 6;
node[root[5]].value = 4;
UpdateTree(root[1]);
UpdateTree(root[5]);
Query(1, 1, 5);
cout << Max;
return 0;
}
相關文章
- 線段樹入門
- 線段樹入門(Segment Tree)
- 線段樹模版:從入門到入墳
- HDU 1754 I Hate It 線段樹入門
- 深入理解線段樹
- HDU 1556 Color the ball 線段樹入門題
- POJ 2777 Count Color 線段樹入門題
- 線段樹 - 多組圖帶你從頭到尾徹底理解線段樹
- POJ 2828 Buy Tickets 線段樹入門(建樹稍微有點抽象)抽象
- POJ 2582 Mayor's posters 線段樹入門題+離散化
- 線~段~樹
- 線段樹
- HDU 1166 敵兵佈陣 線段樹入門題目
- 線段樹 hate it
- 【模版】線段樹
- 01 線段樹
- 線段樹--RMQMQ
- 李超線段樹
- 線段樹模板
- POJ 3264 Balanced Lineup 線段樹入門(點的查詢)
- (hdu 1166)敵兵佈陣(線段樹入門,單點更新)
- ut.cpp 最大線段並減線段交 [線段樹]
- 線段樹筆記筆記
- 權值線段樹
- 線段樹進階
- 理解線段樹這一篇文章就夠啦!
- 線段樹(毒瘤)總結
- 線段樹模板總結
- 線段樹(超詳解)
- 第二課——線段樹
- 線段樹簡單思路
- 線段樹擴充套件套件
- 線段樹 transformation——hdu 4578ORM
- 可持久化線段樹持久化
- 資料結構之樹( 線段樹,字典樹)資料結構
- 資料結構-線段樹資料結構
- 關於線段樹基礎
- 淺談線段樹(Segment Tree)