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

2022-05-19 03:29:07 字數 1393 閱讀 4056

區間修改與區間查詢

今天老糊塗了,樹狀陣列忘記了,基本的只要單點修改+區間查詢功能,如果要進行區間加操作,需要把樹狀陣列進行改造。

我們首先來回顧樹狀陣列的功能:

lowbit(x&(-x)):返回二進位制最低位

1的值:比如

x=1010

那麼lowbit值為2

。x+lowbit(x):把最後一位二進位制最低位

1,往前進一位。

x-lowbit(x):去掉最後一位二進位制最低位1。

我們認為凡是x+lowbit(x)代表父親節點,

x-lowbit(x)

代表兒子節點。

儲存過程:

for (int i=x;i<=n;i+=lowbit(i))^nc[i]-\sum _1^nc[i]*(i-1)$

$=\sum _1^nc[i]*(n-i+1)$

因此我們需要維護兩個值:差分陣列

c[i]=a[i]-a[i-1]

和b[i]=(c[i])*(i-1)

c[i]還是與原來的樹狀陣列一樣更新,

c[i]+x

即可b[i]=c[i]*(i-1)那麼

b[i]=(c[i]+x)*(i-1)

即b[i]=(c[i])*(i-1)+x*(i-1)

我們更新

x*(i-1)

即可更新效果:把x位置後面所有的數的值

+w[l,r]+w=update(r,w)-update(l-1,w)

更新效果:把l位置到

r位置所有的數的值

+w由上面證明可知:

$\sum_1^n a[i] = n*\sum_1^n c[i] - \sum_1^n b[i] $

和以前一樣求和即可,求和式子換成上面那種即可

更新效果:$sum(x)=\sum_1^x a[i]$

#include#include

#include

#include

using

namespace

std;

int sum1[1000

];int sum2[1000

];int a[1000

];int

n,m;

int lowbit(int

x)void update(int x,int w)

}void range_update(int l,int r,int val)//

更新效果:把l位置到r位置所有的數的值+w

int sum(int x)

return

ans;

}int range_ask(int l,int r)

intmain()

}return0;

}

---恢復內容結束---

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

今天,我們再在樹狀陣列上進一步突破,我們來講一講區間修改和區間查詢。同樣的,這需要各位對樹狀陣列的基本知識有所了解,大家可以看看我的另一篇文章 樹狀陣列趣解。下面進入正題。同樣的,我還是先給 再講解。其實,我個人比較喜歡直接看 有時,看別人的解釋,反而看得稀里糊塗,不如先看看 自己會有自己的理解,然...

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

單點更新,區間查詢 我們知道,樹狀陣列最基本的功能是 單點更新,區間查詢 如下 int lowbit int x void add int x,int val int ask int x return res 區間更新,單點查詢 通過 單點更新,區間查詢 功能 差分的思想,我們實現了 區間更新,單點...

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

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