樹狀陣列 區間修改 區間查詢 思緒整理

2021-08-22 07:06:35 字數 1026 閱讀 1860

樹狀陣列真是強啊嚶嚶嚶。

介紹區間修改+區間查詢之前一定要說一下區間修改+單點查詢。

原本樹狀陣列只能用於單點修改+區間查詢。但是把原陣列的差分陣列做成樹狀陣列就可以做到區間修改+單點查詢。

即c[i]=a[i]-a[i-1](a[0]=0),然後把c陣列建成樹狀陣列c ' ;這樣對於a[i]就可以用sum(c ' [j] (j=1->i) )求得,利用樹狀陣列性質可以logn求得結果。

考慮如下式子:sum(a[i] (i=1->j) )=j*c[1]+(j-1)*c[2]+……+1*c[j];

j*a[j]-sum(a[i] (i=1->j) )=0*c[1]+1*c[2]+……+(j-1)*c[j];

於是我們可以用陣列d[i]=(i-1)*c[i]做成樹狀陣列維護結果;

sum(a[i] (i=1->j) )=j*getsum(a,j)-getsum(d,j);

求原陣列區間和的時候 sum(a[i] (i=l->r) )=sum(a[i] (i=1->r) )-sum(a[i] (i=1->l-1) );代入方法即可。

重點是兩個陣列的更新:

差分樹狀陣列c ' 的更新:當給[l,r]增加x時,只需要從c ' [l]增加x並向上lowbit增加x,並且從c ' [r+1]增加-x並向上lowbit增加-x即可。

維護陣列的更新:首先可知d[i]=(i-1)*c[i]; 當差分陣列更新增量x的時候,例如c[l]增加了x,l的累加lowbit的位置的c也要累加x,那麼由於d[i]=(i-1)*c[i];這些位置對應的d也要同時增加(l-1)*x;

問題是為什麼對於d[r+1]是向上累加r*x。

我們知道d陣列是同比與c陣列變換的。在區間更新的時候,僅僅是讓c[l]增加了x,c[r+1]增加了-x,為了讓d陣列同比與c陣列變化,所以d[r+1]應該向上累加r*(-x);

應該保持的原則是這樣的,c是差分陣列,d[i]=(i-1)*c[i]   所以在變換的時候,我們更應該關注的是原陣列,而不是做成樹狀陣列的陣列。我們只是按照樹狀陣列的方式向上更新,但是初始點是哪個,具體更新多少是根據原陣列c和d的關係來看。

樹狀陣列 區間修改,區間查詢

也許更好的閱讀體驗 好東西,以後可以不打線段樹了 本篇假定讀者都會最基礎的兩種樹狀陣列,即區改單查和單改區查 思考如何維護乙個區間的值,想到了差分 對乙個差分陣列做一次字首和可以得到每個位置的值 再對每個位置累加一下就是乙個區間的值 公式化的講,就是 設差分陣列為 c 則每個位置的值 val i s...

樹狀陣列區間修改區間查詢

題面 首先,我們要推乙個柿子。displaystyle sum a i 把a i 用差分陣列表示出來,就可以寫成 displaystyle sum sum d i 我們考慮一下,每個d i 出現的次數是一定的。那我們可以換一下列舉順序,先列舉d i 在列舉他出現的次數,就可以變成 displayst...

樹狀陣列高階 區間修改 區間查詢

區間修改與區間查詢 今天老糊塗了,樹狀陣列忘記了,基本的只要單點修改 區間查詢功能,如果要進行區間加操作,需要把樹狀陣列進行改造。我們首先來回顧樹狀陣列的功能 lowbit x x 返回二進位制最低位 1的值 比如 x 1010 那麼lowbit值為2 x lowbit x 把最後一位二進位制最低位...