單點更新,區間查詢
我們知道,樹狀陣列最基本的功能是 單點更新,區間查詢
**如下:
int lowbit(int x)
void add(int x, int val)
}int ask(int x)
return res;
}
區間更新,單點查詢
通過 「單點更新,區間查詢」 功能+差分的思想,我們實現了: 區間更新,單點查詢
\(c[i]=a[i]-a[i-1]\),所以,以c[i] 建立樹狀陣列,\(a[i]=ask(i)\)
因為\(a[i]=\sum_^i c[i]\)
所以我們想讓區間\([l,r]\) 每乙個a[i] 都加上x的話,我們只需要\(add(l,x),add(r+1,-x)\)
進入我們今天的主題 :區間更新,區間查詢
我們知道陣列a[i]的差分陣列 c[i] 滿足:\(a[i]=\sum_^i c[i]\)
那麼\(\sum_^na[i]=\sum_^n^ic[i]}\)
\(\sum_^na[i]=c[1]+(c[1]+c[2])+(c[1]+c[2]+c[3])+\dots+\sum_^n c[i]\)
\(\sum_^na[i]=n*(c[1]+c[2]+c[3]+\dots+c[n])-(c[2]+2*c[3]+3*c[4]+\dots+(n-1)*c[n])\)
\(\sum_^na[i]=n*(\sum_^n c[i])- \sum_^n(i-1)*c[i]\)
於是我們可以用2個樹狀陣列,分別維護 \(c[i]\) 和\((i-1)*c[i]\),陣列名分別叫tree1,tree2
區間\([l,r]\) 的sum和就等於\(query(r)-query(l-1)\)
\(query(x)=x*ask(tree1,x)-ask(tree2,x)\)
如果怕詢問\([0,x]\) 等情況\((i-1)<0\),可以第二個樹狀陣列tree2維護\((i*c[i])\),根據差分陣列的思想,並不影響結果。
**:
long long tree1[maxn];
long long tree2[maxn];
long long ask(long long *tree, long long x)
return sum;
}void add(long long *tree, long long x, long long y)
}ll query(ll l, ll r)
void op(ll l, ll r , ll x)
樹狀陣列高階 區間修改 區間查詢
區間修改與區間查詢 今天老糊塗了,樹狀陣列忘記了,基本的只要單點修改 區間查詢功能,如果要進行區間加操作,需要把樹狀陣列進行改造。我們首先來回顧樹狀陣列的功能 lowbit x x 返回二進位制最低位 1的值 比如 x 1010 那麼lowbit值為2 x lowbit x 把最後一位二進位制最低位...
樹狀陣列再高階(區間修改 區間查詢)
今天,我們再在樹狀陣列上進一步突破,我們來講一講區間修改和區間查詢。同樣的,這需要各位對樹狀陣列的基本知識有所了解,大家可以看看我的另一篇文章 樹狀陣列趣解。下面進入正題。同樣的,我還是先給 再講解。其實,我個人比較喜歡直接看 有時,看別人的解釋,反而看得稀里糊塗,不如先看看 自己會有自己的理解,然...
樹狀陣列 區間修改,區間查詢
也許更好的閱讀體驗 好東西,以後可以不打線段樹了 本篇假定讀者都會最基礎的兩種樹狀陣列,即區改單查和單改區查 思考如何維護乙個區間的值,想到了差分 對乙個差分陣列做一次字首和可以得到每個位置的值 再對每個位置累加一下就是乙個區間的值 公式化的講,就是 設差分陣列為 c 則每個位置的值 val i s...