線段樹解析(一)

2021-10-08 18:30:34 字數 2361 閱讀 1155

一、線段樹的應用場景

1.用於解決區間問題,例如求某個區間的和、最大值、最小值。

2.支援的操作有單點修改、區間修改、區間查詢。

二、線段樹

線段樹的核心思想在於:

1.線段樹的每個節點預先維護好所對應區間所需要的資訊。

2.對於一次查詢,將詢問區間[l,r]拆分到線段樹對應的節點上,通過合併這些節點已經處理好的資訊快速得到答案。

3.對於一次單點修改、將其對應的葉子節點到根的所有節點資訊更新。

三、線段樹**

以下**以求區間的最小值為例

1.建樹

void build(int x, int l, int r)

int mid = (l + r) / 2;

build(2 * x, l, mid);

build(2 * x + 1, mid + 1, r);

tree[x].value = min(tree[2 * x].value, tree[2 * x + 1].value);

}

2.單點修改

void change(int x, int pos, int w)

int mid = (tree[x].l + tree[x].r) / 2;

if (pos <= mid)

change(2 * x, pos, w);

else

change(2 * x + 1, pos, w);

tree[x].value= min(tree[2 * x].value, tree[2 * x + 1].value);

}

3.區間查詢

int query(int x, int l, int r)

int mid= (tree[x].l + tree[x].r) / 2;

if (l > mid)

return query(2 * x + 1, l, r);

else if(r<=mid)

return query(2 * x , l, r);

else

return min(query(2 * x, l, mid),query(2*x+1,mid+1,r));

}

4.區間修改--懶標記

void update(int x,int w)

void push_down(int x)

void push_up(int x)

int change(int x, int l, int r, int w)

if (tree[x].lazy_tag != -1)

push_down(x);

int mid = (tree[x].l + tree[x].r) / 2;

if (l > mid)

return change(2 * x + 1, l, r,w);

else if (r <= mid)

return change(2 * x, l, r,w);

else

; push_up(x);

}

5區間查詢--懶標記

int query(int x, int l, int r)

if (tree[x].lazy_tag != -1)

push_down(x);

int mid= (tree[x].l + tree[x].r) / 2;

if (l > mid)

return query(2 * x + 1, l, r);

else if(r<=mid)

return query(2 * x , l, r);

else

return min(query(2 * x, l, mid),query(2*x+1,mid+1,r));

}

6.線段樹的離散化

比如資料過大時,建立線段樹無法開闢那麼多單元,此時就要用到離散化了。

具體步驟如下:

1.sort(a,a+n)排序,將要用到的區間或者點集排序;

2.unique(a,a+n)去重,返回最後那個完成去重的點往後乙個位置的位址,再減乙個a得到去重後的陣列大小;

3.lower-boud(a,a+n,x)返回a[0]-a[n-1]中第乙個》=x的位址,若無,返回最末端的值,即a[n];

for(int i=0;isort(sub,sub+n);

int size=unique(sub,sub+n)-sub;

for(int i=0;ia[i]=lower_bound(sub,sub+size,a[i])-sub+1;

線段樹解析

概念 線段樹是一種特殊的結構,它每個節點記錄著乙個區間和這個區間的乙個計數,表示此區間出現的次數。線段樹分為構造build部分,插入insert部分,以及查詢query部分。其主要的思想就是用空間換時間,來使一些特殊的問題的時間複雜度減少。比如對於一段空間或者乙個數字的出現次數,以線段樹來查詢可以使...

線段樹模板一

線段樹練習題1 time limit 10000ms memory limit 65536k total submit 263 accepted 93 case time limit 1000ms description 桌子上零散地放著若干個盒子,桌子的後方是一堵牆。如右圖所示。現在從桌子的前方射...

線段樹學習 一

看到uestc的資料結構專題快要結束了,感覺自己真心浪費了好多時間,沒有像鑫航學姐那樣叮囑的一樣,緊緊的跟住訓練。所以下決心認認真真的開始學習下線段樹的知識,以前對於線段樹的學習都是一知半解的,就是說,我只知道線段樹是用來單點更新和區間查值的,其實,線段樹的功能遠遠不止這些。先來說下,線段樹是用來求...