線段樹就是像下圖的一種特殊的數,有儲存,查詢,修改等操作
需要用到
線段樹的操作主要分為兩種:
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...