線段樹初學

2021-07-06 08:00:30 字數 1728 閱讀 5543

線段樹就是像下圖的一種特殊的數,有儲存,查詢,修改等操作

需要用到

線段樹的操作主要分為兩種:

1,對單個區間儲存數值,查詢,修改

2,對連續區間進行儲存,查詢,修改

起始兩種操作就是乙個函式的區別,難點也是在這個函式上。第二種操作多了乙個函式的使用,難度會大點

線段數的使用需要用到三個函式,

1,初始化    2,修改    3查詢

線段樹的初始化就是以二分的思想建立一顆樹,如需要建立區間(a,b)的線段樹,先就是把(a,b) 二分為(a,c)

(d,b)。   (a,c)作為(a,b)的左孩子,(d,b)作為(a,b)的右孩子,以此類推

**: 

void make_build(node *cur,int l,int r)//初始化 

else

cur->leftchild=cur->rightchild=null;

}

接著就是修改,也是利用二分的思想,逐層去尋找符合要求的區間

要注意的就是乙個函式

**:     

void make_update(node *cur)

這個函式就像乙個中轉站,比如把(1,5)存入,我們的想法是當找到線段樹中(1,5)區間就可以了,不要再繼          續往下找,直到存到每乙個葉子節點的區間去。但是我們要查詢(1,2)時,我們會發現(1,2)區間並沒有賦              值,這裡就要用到

void make_update(node *cur)函式。當查詢(1,2)的值時,他的作用就是把(1,5)區間的值        向下傳遞。

查詢函式其實就是把修改函式改下,沒什麼好講的

完整**

#include#include#includeusing namespace std;

struct node

;void make_build(node *cur,int l,int r)//初始化

else//忘記加

cur->leftchild=cur->rightchild=null;

}void make_update(node *cur)

void make_change(node *cur,int l,int r,int date)//修改

else

if (r<=md)

if (l>md)

if (l<=md && r>md)//改變的區間橫跨左右兒子區間

cur->dt=cur->leftchild->dt+cur->rightchild->dt;//忘記加 }}

int make_query(node *cur,int l,int r)//查詢

else

if (r<=md)

if (l>md)

if (l<=md && r>md)

return as;

} //return as;放在外面

}int main()

if (k==2)

if (k==0)

p=0;

} break;

} return 0;

}

初學樹套樹 線段樹套Treap

樹套樹是乙個十分神奇的演算法,種類也有很多 像什麼樹狀陣列套主席樹 樹狀陣列套值域線段樹 zkw 線段樹套 vector 等等。不過,像我這麼弱,當然只會最經典的線段樹套 treap 啦。線段樹我相信大家都會的,treap 可以看一下這篇部落格 簡析平衡樹 二 treap 線段樹套 treap 的思...

線段樹的初學認知及操作步驟

線段樹是一種二叉搜尋樹,與區間樹相似,它將乙個區間劃分成一些單元區間,每個單元區間對應線段樹中的乙個葉結點。使用線段樹可以快速的查詢某乙個節點在若干條線段 現的次數,時間複雜度為o logn 而未優化的空間複雜度為2n,實際應用時一般還要開4n的陣列以免越界,因此有時需要離散化讓空間壓縮。線段樹主要...

線段樹 02 構建線段樹

public inte ce merger 不能再縮小的基本問題是 對treeindex指向的節點的情況進行討論 public class segmenttree 在treeindex的位置建立表示區間 l.r 的線段樹 private void buildsegmenttree int treei...