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