對一列數,對每次詢問輸出對應區間的和,每次修改只修改乙個數的值。。。
定義:
structtree
由於線段樹還是相對比較平衡的,所以可以使用陣列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()即可。
structtree
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...