遇到區間查詢修改,相信大家一般用的都是線段樹,
但常數遠遠沒有樹狀陣列優秀,
這裡就來談談如何用樹狀陣列解決區間問題
(同時可以用於多維問題)
首先,相信大家一定會用樹狀陣列做區間加,單點查詢的問題,
差分一下即可;
那麼對於區間查詢,怎麼做呢?
要做到區間查詢,就要能計算乙個點的值對後面的值的影響,
多開乙個陣列f[i]=(n-i+1)*f[i],(f為用來差分的陣列)
差分的話當然是這個點的值對後面的每個點都有影響,所以權值乘上那麼多,
但很顯然,在計算區間是,它的影響沒有那麼大,
設查詢的區間是l,r,那麼它在答案中應該是:(r−
i+1)
∗f[i
]=f[
i]−(
n−r)
∗f[i
](r-i+1)*f[i]=f[i]-(n-r)*f[i]
(r−i+1
)∗f[
i]=f
[i]−
(n−r
)∗f[
i],發現(n-r)對於任意的f[i]都是一定的,也就是可以區間求和以後直接乘上(n-r)減掉f多出來的部分,再加上l之前的影響,
這樣既可實現用樹狀陣列解決區間修改查詢問題,
那麼現在問題來了,如何用樹狀陣列實現二維或多維的求和,
以二維為例,
對平面上的乙個矩形加/減,求矩形裡點的和,
我們需要多開3個陣列,
f1[i][j]=(m-j+1)*(n-i+1)*f[i],
f2[i][j]=(n-i+1)*f[i],
f3[i][j]=(m-j+1)*f[i],
用矩陣和的套路,減掉右邊左邊,加上右下角的,即可,
對於前面的影響,與處理後面的差不多,
(這個需要大家自己感受一下,實在不會就看標吧)
(重點在gans這個函式)
void change(int x,int y,int e)
}void find(int x,int y)
}void add(int x,int y,int x1,int y1)
int gans(int x,int y,int x1,int y1)
樹狀陣列區間修改
有時,我們要支援區間修改,區間查詢。線段樹可以做到。但是樹狀陣列更好寫。1d的情況 設 b i a i a i 1 則 a i b 1 b i a 1 a l b 1 b 1 b 2 b 1 b l a 1 a l l b 1 l 1 b 2 b l sum l i 1 b i 如果我們維護 b i...
樹狀陣列維護區間和和區間修改
可以用樹狀陣列在 n logn 內,雖然線段樹也能,但是樹狀陣列的 空間都要比它優越得多.首先我們可以用差分的方法使區間修改可以在log的複雜度完成,但重點在於區間和的查詢.我們知道,此時num i a 1 a 2 a i 可以利用樹狀陣列快速求出.而區間和則是 a 1 a 2 a i a 1 a ...
樹狀陣列 區間修改,區間查詢
也許更好的閱讀體驗 好東西,以後可以不打線段樹了 本篇假定讀者都會最基礎的兩種樹狀陣列,即區改單查和單改區查 思考如何維護乙個區間的值,想到了差分 對乙個差分陣列做一次字首和可以得到每個位置的值 再對每個位置累加一下就是乙個區間的值 公式化的講,就是 設差分陣列為 c 則每個位置的值 val i s...