黑科技 用樹狀陣列解決區間修改查詢問題

2021-08-06 05:18:26 字數 1135 閱讀 8019

遇到區間查詢修改,相信大家一般用的都是線段樹,

但常數遠遠沒有樹狀陣列優秀,

這裡就來談談如何用樹狀陣列解決區間問題

(同時可以用於多維問題)

首先,相信大家一定會用樹狀陣列做區間加,單點查詢的問題,

差分一下即可;

那麼對於區間查詢,怎麼做呢?

要做到區間查詢,就要能計算乙個點的值對後面的值的影響,

多開乙個陣列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...