區間修改與區間查詢
今天老糊塗了,樹狀陣列忘記了,基本的只要單點修改+區間查詢功能,如果要進行區間加操作,需要把樹狀陣列進行改造。
我們首先來回顧樹狀陣列的功能:
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...