一維樹狀陣列
我學習的版本是這樣的
區間修改:
我們假設sigma(r,i)表示r陣列的前i項和,呼叫一次的複雜度是log2(i)
設原陣列是a[n],差分陣列c[n],c[i]=a[i]-a[i-1],那麼明顯地a[i]=sigma(c,i),如果想要修改a[i]到a[j](比如+v),只需令c[i]+=v,c[j+1]-=v
區間查詢:
在基於樹狀陣列的基礎操作:單點修改、區間查詢上,我們可以這樣操作
首先觀察
a[1]+a[2]+...+a[n]
= (c[1]) + (c[1]+c[2]) + ... + (c[1]+c[2]+...+c[n])
= n*c[1] + (n-1)*c[2] +... +c[n]
= n * (c[1]+c[2]+...+c[n]) - (0*c[1]+1*c[2]+...+(n-1)*c[n]) (式子①)
那麼我們就維護乙個陣列c2[n],其中c2[i] = (i-1)*c[i]
每當修改c的時候,就同步修改一下c2,這樣複雜度就不會改變
那麼式子①
=n*sigma(c,n) - sigma(c2,n)
於是我們做到了在o(logn)的時間內完成一次區間和查詢
#include#include一維樹狀陣列 區間修改 區間查詢(1)#include
#include
#define n 3010
using
namespace
std;
intn,q,num[n],c1[n],c2[n];
inline
int lowbit(int
x)inline
int add(int *r,int u,int
del)
inline
int sum_(int *r,int
v)inline
void
jimmy()
for(int i=1,type;i<=q;i++)
if(type==2
) }
}int
main()
區間修改 區間查詢
學完本來高高興興
然後一看二維樹狀陣列
那我二維怎麼把乙個點差分成乙個2維的i*j啊
然後就懵逼了
所以這種辦法雖然是正確的,但是不利於推廣
所以接下來介紹一下另一種可以推廣的姿勢的樹狀陣列區間修改+區間查詢的辦法
然後,**一篇dalao的部落格
orzaireen ,這種樹狀陣列理解完一維就可以輕鬆推廣到二維
#include#include一維樹狀陣列正確姿勢#include
#include
#define n 3010
using
namespace
std;
struct
bit inline
void add(int x,int
del)
inline
int sum(int
x)};
struct
bit inline
void add(int l,int r,int
del)
inline
void sum(int l,int
r)};
inline
void
jimmy()
intmain()
#include#include二維樹狀陣列正確姿勢#include
#include
using
namespace
std;
struct
bit_2d
inline
void add(int x,int y,int
del)
inline
int sum(int x,int y,int
del)
}s;struct
bit_2d
inline
void add(int x,int y,int
del)
inline
void add(int x,int y,int
del)
inline
int sum(int x,int
y) inline
int sum(int a,int b,int c,int
d) }s;
inline
void
jimmy()
intmain()
x'>δxδx
表示區間[x,
n]'>[x,
n][x,n]
的共同增量.
利用的差分的思想,對於區間[l,
r]'>[l,
r][l,r]
,每次修改δl,
δr+1
'>δl,
δr+1
δl,δr+1
即可.
這就解決了區間加的問題.x=
ai′+
∑i=1
xδi'>ax=
a′i+
∑xi=
1δiax=ai′+∑i=1xδi s
x=∑i
=1xa
i=∑i
=1xa
i′+∑
i=1x
(x−i
+1)δ
i=∑i
=1xa
i′+∑
i=1x
δi×(
x+1)
−∑i=
1xδi
×i'>sx=
∑i=1
xai=
∑i=1
xa′i
+∑i=
1x(x
−i+1
)δi=
∑i=1
xa′i
+∑i=
1xδi
×(x+
1)−∑
i=1x
δi×i
sx=∑i=1xai=∑i=1xai′+∑i=1x(x−i+1)δi=∑i=1xai′+∑i=1xδi×(x+1)−∑i=1xδi×i
所以只需維護δi,
δi×i
'>δi,
δi×i
δi,δi×i
的字首和即可.
學習筆記 樹狀陣列
以下 為樹狀陣列最常用的幾個操作 1.low bi t mathrm lowbit function lowbit x longint int64 begin exit x and x end 2.單點修改 procedure replace x,y int64 var i int64 begin ...
樹狀陣列學習筆記
在學習完了線段樹後,聽說樹狀陣列能寫的題,線段樹都能做,所以一直沒有詳細的學習樹狀陣列 直到碰到了一道卡線段樹的題目,因為線段樹運用了很多遞迴,所以常數比較大,容易被卡 現在總結一下樹狀陣列 1 樹狀陣列個人認為就是字首和演變而來的 2 單點更新 當你要更新某個點的值時,你要從下面到上面依次更新過去...
樹狀陣列學習筆記
樹狀陣列 binary index tree,bit 也是很多人心中最簡潔優美的資料結構之一。最簡單的樹狀陣列支援兩種操作,時間複雜度均為 當然,樹狀陣列能維護的不侷限於加法,支援的操作也不止這兩種,甚至有大佬能用樹狀陣列實現平衡樹,但這篇筆記不會深入討論 因為我也還不是很懂 回顧一下,我們說,我們...