單點更新,區間查詢線段樹

2021-10-01 21:07:59 字數 2089 閱讀 4426

線段樹的空間複雜度是4n

#include

#include

#include

using namespace std;

const

int maxn=

100005

;const

int inf=

0x3f3f3f3f

;int n,a[maxn]

;struct node//結點

tree[maxn*4]

;//樹結點儲存陣列

void

build

(int k,

int l,

int r)

//建立線段樹,k表示儲存下標,區間[l,r]

int mid,lc,rc;

mid=

(l+r)/2

;//劃分點

lc=k*2;

//左孩子儲存下標

rc=k*2+

1;//右孩子儲存下標

build

(lc,l,mid)

;build

(rc,mid+

1,r)

; tree[k]

.mx=

max(tree[lc]

.mx,tree[rc]

.mx)

;//結點的最大值等於左右孩子最值的最大值

}

點更新是指修改乙個元素的值,例如將a[i]修改為v。仍然採用遞迴的方法進行點更新,其過程如下:

1)如果是第i個元素所在的葉子結點(l=r且l=i),則修改結點的最值為v;

2)如果是非葉子結點,則判斷在左子樹中更新還是在右子樹中更新;

3)返回時更新結點的最值

//將a[i]修改更新為v

int mid,lc,rc;

mid=

(tree[k]

.l+tree[k]

.r)/2;

//劃分點

lc=k*2;

//左孩子儲存下標

rc=k*2+

1;//右孩子儲存下標

if(i<=mid)

update

(lc,i,v)

;//到左子樹修改更新

else

update

(rc,i,v)

;//到右子樹修改更新

tree[k]

.mx=

max(tree[lc]

.mx,tree[rc]

.mx)

;//返回時修改更新最值

}區間查詢

區間查詢是指乙個個區間的最值。仍然採用遞迴的方法進行區間查詢,其過程如下:

1)如果結點的區間被查詢區間[l,r]覆蓋,則返回該結點的最值;

2)判斷在左子樹查詢,右子樹查詢;

3)返回最值。

//求區間[l..r]的最值

void

print

(int k)

}int

main()

線段樹

區間更新和區間最值查詢

I Hate It 線段樹單點更新區間查詢

很多學校流行一種比較的習慣。老師們很喜歡詢問,從某某到某某當中,分數最高的是多少。這讓很多學生很反感。不管你喜不喜歡,現在需要你做的是,就是按照老師的要求,寫乙個程式,模擬老師的詢問。當然,老師有時候需要更新某位同學的成績。input 本題目包含多組測試,請處理到檔案結束。在每個測試的第一行,有兩個...

線段樹 區間更新 區間查詢

題意 題解 如果採用單點更新的思路對區間進行更新的話時間複雜度會比較高,因此用了乙個lazy陣列 俗稱懶人標記 它為什麼叫懶人標記呢,比如更新的區間為 l,r z,而l到r覆蓋了線段樹某乙個節點的區間,那麼可以將該節點對應的lazy陣列的值加上z,同時更新該節點的值,這樣就可以避免更新它子孫節點的值...

線段樹 學習 模板 單點更新 區間更新

線段樹是幹什麼的?有一列數,每次可以進行以下三種操作中的一種 1 給指定區間中的每個數都加上某個值 2 將指定區間內的所有數置成某乙個統一的值 3 詢問乙個區間上的最小值 最大值 所有數的和。樸素做法怎麼做?用線性表儲存,每種操作,對待處理或待詢問區間中的每個元素都逐一進行處理。複雜度多少?假設這個...