首先考慮樹狀陣列的一維區間修改與求和
把數列差分,那麼對l和r的區間加就可以變成l位置的加和r+1的減
設差分陣列為t
修改前陣列為a
修改後陣列為b
那麼修改後的答案 an
s=∑i
=lrb
[l]=
∑i=l
ra[i
]+b[
i]∗(
r−i+
1)=(
r+1)
∑i=l
ra[i
]+b[
i]−∑
i=lr
a[i]
∗ia[i]提前處理好,分別用兩個樹狀陣列維護∑r
i=lb
[i] 和
∑ri=
la[i
]∗i
一維還是很簡單的
二維略複雜一些
這次直接忽略a,式子裡也不寫了
樹狀陣列中的[x,y]為[1,1]~[x,y]的結果
對於[x1,y1,x2,y2]相當於在四個角的位置分別加減
具體來說就是[x2,y2]-[x2,y1-1]-[x1-1,y2]+[x2-1,y2-1]
這是對於查詢
對於修改是修改[x,y]到[n,m]的東西的
所以設x為增加值,對於修改就相當於分別做下面四個東西
[x1,y1]+x,[x1,y2+1]-x,[x2,y1+1]-x,[x2+1,y2+1]+x an
s=∑i
=1x∑
j=1y
b[i]
[j]∗
(x−i
+1)∗
(y−j
+1)=
(x+1
)(y+
1)∑i
=1x∑
j=1y
b[i]
[j]−
(y+1
)∑i=
1x∑j
=1yb
[i][
j]∗i
−(x+
1)∑i
=1x∑
j=1y
b[i]
[j]∗
j+∑i
=1x∑
j=1y
b[i]
[j]∗
i∗j
那麼,用四個樹狀陣列分別存下 ∑x
i=1∑
yj=1
b[i]
[j]
∑xi=
1∑yj
=1b[
i][j
]∗i
∑xi=
1∑yj
=1b[
i][j
]∗j
∑xi=
1∑yj
=1b[
i][j
]∗i∗
j 求值即可
**如下
ll get(ll z,ll x,ll y)
ll sum(ll x,ll y)
void put(ll z,ll x,ll y,ll w)
void ins(ll x,ll y,ll w)
int main()
樹狀陣列的區間修改求和
差分陣列 c i a i a i 1 然後可以發現 a i a 1 a 2 a 1 a 3 a 2 a i a i 1 c 1 c 2 c i 1,區間修改單點查詢 修改a l 到a r 值 的時候,只需修改c l 和c r 1 然後求一次c i 的字首和就可以。2,區間修改區間查詢 還是利用差分的...
單點修改,區間查詢 一,二維
不難想到,用乙個陣列來模擬 就比如,單點修改就是這 時間複雜度為o 1 a x k 求區間內的和 for int i l 1 i r i sum a i 這樣的時間複雜度為o n 如果查詢次數足夠多,就會超時 解決方法一 字首和 這樣在輸入時預處理,查詢只要o 1 時間。但是仔細想想,這樣的話,修改...
樹狀陣列 區間求和
樹狀陣列 是乙個查詢和修改複雜度都為log n 的資料結構,假設陣列a 1.n 那麼查詢a 1 a n 的時間是 log n 級別的。所以如果要解決 陣列中的元素不斷被修改,怎麼才能快速地獲取陣列中連續m個數的和 這個問題的話,用樹狀陣列就再好不過了 首先,什麼是樹狀陣列呢?樹狀陣列就是用另外乙個陣...