模板 樹狀陣列

2021-08-08 15:32:40 字數 1851 閱讀 9745

樹狀陣列可以解決什麼樣的問題

對於包含n個元素的整數陣列a,每次可以 

1. c(i, j): 修改乙個元素a[i] = j 

2. q(i): 詢問字首si=a1+a2+…+ai的值

lowbit值

在說樹狀陣列之前,我們不得不說一下lowbit值 

設c[i]=a[i-2k+1]+…+a[i],其中k為i在二進位制下末尾0的個數 

令lowbit(i)=2^k 

例如, i=1001010110010000, 則k=4 

因為補碼的原理是:正數變負數時,按位取反 末位加一 

所以對於正數x 我們不難得到lowbit公式: lowbit(x)=x and -x

樹狀陣列是乙個動態維護字首和的資料結構

網上最「火」的圖應該是這個 

修改操作

當修改c[x]時, 可能有很多c隨之修改 

例如,對於x=76=01001010,可以得到: 

p1= 01001010 

p2= 01001100 

p3= 01010000 

p4= 01100000 

p5= 10000000 

所以 •p1=x 

•pi+1=pi+lowbit(pi) 

則需要依次修改c[p1],c[p2],…

詢問操作

如何計算a[1]+…+a[x]? 

首先累加c[x], 因為它的定義是以x結尾的連續和,它的連加起點是c[i-lowbit(i)+1] 

因此問題轉化為了求a[1]+…+a[i-lowbit(i)] 

由此, 我們得到遞推式 

•p1=x 

•pi+1=pi-lowbit(pi) 

則只需要累加c[p1], c[p2], …

清晰一點就像這樣 

【模板】樹狀陣列 1 洛谷p3374

裸樹狀陣列**:

#include

#define lowbit(x) (x&(-x))

#define maxn 500050

using

namespace

std;

int tree[maxn];

int n,m;

inline

void add(int x,int num)

}inline

int search(int x)

return re;

}int main()

for(int i=1;i<=m;++i)

return

0;}

【模板】樹狀陣列 2 洛谷p3368

裸樹狀陣列+差分

#include

#define lowbit(x) (x&(-x))

#define maxn 500050

using

namespace

std;

int tree[maxn];

int a[maxn];

int n,m;

inline

void add(int x,int num)

}inline

int search(int x)

return re;

}int main()

else

}return

0;}

樹狀陣列模板

假設有一列數 1 i n 支援如下兩種操作 1.將ai的值加d。2.輸出ai ai 1 aj 1 i j n 樹狀陣列是一種特殊的資料結構,這種資料結構的時空複雜度和線段樹相似,但是它的係數要小得多 hdu 1166 敵兵布陣 題目 a國在海岸線沿直線布置了n個工兵營地。由於採取了某種先進的監測手段...

樹狀陣列模板

已知乙個數列,你需要進行下面兩種操作 1.將某區間每乙個數數加上x 2.求出某乙個數的和 這種水水的樹狀陣列,博主就不做介紹,直接上 希望大家可以多多捧場!include include include include include include include include include ...

樹狀陣列模板

樹狀陣列 binary indexed tree bit fenwick tree 是乙個查詢和修改複雜度都為log n 的資料結構。主要用於查詢任意兩位之間的所有元素之和,但是每次只能修改乙個元素的值 經過簡單修改可以在log n 的複雜度下進行範圍修改,但是這時只能查詢其中乙個元素的值。一,改點...