點更新線段樹模板

2022-03-14 09:22:43 字數 1057 閱讀 6675

對一列數,對每次詢問輸出對應區間的和,每次修改只修改乙個數的值。。。

定義:

struct

tree

由於線段樹還是相對比較平衡的,所以可以使用陣列t來儲存這棵樹,

對與某個節點i,t[i*2]就是左子樹,t[i*2+1]就是右子樹

建樹:線段樹的思想是每個節點記錄區間的資訊,某點區間1~n,則1~n/2為其左子樹,n/2+1~n為其右子樹,每次建立子樹方法相同,可以遞迴建樹。。。

至於詢問,如果詢問區間並不是樹上某個確切的節點,就拆分開落到其子樹上,追究到底還是遞迴。。

加和,現在是對點加和還是比較容易的,回溯時將每個節點的sum值更新即可。。。

tree陣列開的大小一般是資料陣列a大小的4倍

一開始資料讀入a陣列中,需要的話請自行更改成其他名字。

buildtree(id,l,r)   初次呼叫id一般是頭結點0,l與r是構造的範圍,初次呼叫為1~n或者0~n-1,注意buildtree時要求a中有值,如果建立乙個空樹,需要把a清零,或者把函式中a[i]出現的地方改為0

update(id,s,w)   初次呼叫id一般是頭結點0,s為需要修改的位置的下標,w為要修改成的值

sum(id,l,r)         初次呼叫id一般是頭結點0,求下標l到r的和的值。

線段樹還可以求最大最小值,把求和改成max()或者min()即可。

struct

tree

t[400001

];int a[100001

];int

p,b,l,r;

int calc(int x,int y)//

加和運算,如果求最大最小值,更改這裡就可以了。

void buildtree(int id,int l,int r,int *a)

else

}void update(int id,int s,int w)//

s點加上w,可以根據需要改成賦值號

else

}int sum(int id,int l,intr)

else

}

區間更新,線段樹

對 l,r 進行區間更新 1 如果結點的區間被查詢區間 l,r 覆蓋,僅對該結點進行更新,並做懶標記,表示該結點被更新過,對該結點的子結點不再進行更新 2 判斷在左子樹查詢,右子樹查詢。查詢過程中,若當前節點帶有懶標記,懶標記下傳給子結點 當前結點懶標記清除,子結點更新並做懶標記 繼續查詢 3 更新...

線段樹之區間更新線段樹

在學習區間更新線段樹之間要先學習單點更新線段樹。情景引入 給乙個長度為n的陣列a,隨機修改區間陣列元素 a l a r 的值,然後求任意區間和。修改操作我們可以想到 for int i l i r i update 但是,這種方法很顯然比較費時,不夠優,所以有了今天要講的區間更新。懶惰標記 在講之前...

樹的區間查詢與更新(線段樹)

原題 include include include include include include include include using namespace std define clr x memset x,0,sizeof x define ll long long define typ...