真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網站制作重慶分公司

線段樹

前置知識

創(chuàng)新互聯(lián)公司2013年成立,先為策勒等服務建站,策勒等地企業(yè),進行企業(yè)商務咨詢服務。為策勒企業(yè)網站制作PC+手機+微官網三網同步一站式服務解決您的所有建站問題。

二叉樹

定義

基本操作復雜度: $ O(logn) $

線段樹是一棵二叉樹,每個節(jié)點表示序列上的一段區(qū)間,其中根節(jié)點表示區(qū)間[1,n]。

從根節(jié)點開始,只要區(qū)間長度不為1,就將區(qū)間劃分為兩半,并分給兩個子節(jié)點。

若當前節(jié)點表示區(qū)間[l,r],

當l≠r時,左孩子表示[l,(l+r)/2],右孩子表示[(l+r)/2+1,r];

當l=r時,該節(jié)點為葉子節(jié)點。

基本性質

性質1

線段樹的總節(jié)點數(shù)為2n-1。

性質2

線段樹的層數(shù)約為 $ log_{ 2 } n $ ,即每個葉節(jié)點到根節(jié)點的距離約為 \(log_{2}n\) 。

性質3

任何區(qū)間都可以用不超過 \(2log_{2}n\) 個節(jié)點組合而成。

編號

線段樹的編號方式通常有兩種:即2i和2i+1作i的孩子或按構建順序編號。

存儲

線段樹的存儲也有兩種方式:多個數(shù)組或struct結構體。

以struct結構體數(shù)組為例:

(lc,rc分別為左右孩子的編號,sum為該區(qū)間的總和。

數(shù)組大小為序列長度兩倍。

至于區(qū)間的左右端點[l,r],可以存儲,也可以遞歸時計算。

若需要節(jié)省空間,則不存儲。)

構建

構建過程遞歸實現(xiàn),

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

(u為當前節(jié)點編號,l,r為區(qū)間端點)

從根節(jié)點開始構建,遞歸時計算并代入l,r,若l=r,該點為葉子節(jié)點,令sum=序列原值,否則,遞歸構建左右孩子,之后令sum=sum左孩子+sum右孩子。

在主程序中:

t=1;

build(1,1,n);

即可。

應用

單點修改

修改過程遞歸實現(xiàn),

void update(int u,int l,int r,int x,int w)

(u當前節(jié)點編號,l和r為區(qū)間端點,x為要修改的位置,w為變化量)

從根節(jié)點開始修改,若當前點為葉子節(jié)點,使sum+=w并返回
否則判斷x在左孩子還是右孩子,遞歸進行修改,之后令sum=左孩子sum+右孩子sum。

在主程序中調用:

update(1,1,n,x,y);

區(qū)間和查詢

查詢過程遞歸實現(xiàn),

void query(int u,int l,int r,int ll,int rr)

(u為當前節(jié)點,l和r是區(qū)間端點,ll和rr分別為所查詢區(qū)間的左右端點)

需要用外層定義變量ans儲存答案。

從根節(jié)點開始,首先判斷查詢區(qū)間與節(jié)點區(qū)間是否完全重合,若重合,ans+=sum并返回,否則判斷查詢區(qū)間是否完全在左孩子或者右孩子,若是則遞歸查詢。否則將查詢區(qū)間拆分,兩側分別遞歸查詢。

在主程序中:

ans=0;

query(1,1,n,x,y);

維護區(qū)間最大值/最小值

區(qū)間修改

我們在線段樹的每個節(jié)點上再儲存一個信息,稱為“標記”,記為tag,表示該節(jié)點所包含的每個位置,都要再加上tag。

首先,像區(qū)間詢問一樣將區(qū)間對應到盡量少的節(jié)點上,

令它們

	sum+=(r-l+1)*w;//增加的區(qū)間和
	tag+=w;//增加標記 

然后將sum信息向上pushup。

區(qū)間修改后的單點/區(qū)間查詢

查詢與之前類似,

查詢過程遞歸實現(xiàn),

void query(int u,int l,int r,int ll,int rr,int w)

但由于標記的出現(xiàn),多了“下傳標記”一步。

下傳標記時,孩子的標記要疊加。

類似于pushup,標記下傳的過程寫入一個

void pushdown(int u,int l,int r)

一個節(jié)點上的tag一定已經計入自身的sum。

在修改和查詢時,只要需要進入子節(jié)點,就一定要pushdown。

注意

當維護信息較多時,為簡化代碼,通常將類似于”a[u].sum=a[a[u].lc].sum+a[a[u].rc].sum”的上傳信息的步驟寫入void pushup(int u)并調用pushup(u);

并非原創(chuàng),僅是整理,請見諒


標題名稱:線段樹
瀏覽地址:http://weahome.cn/article/dsoipoh.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部