樹狀陣列,時間複雜度o(mlogn)明顯優於暴力列舉以及字首和,主要用於單點修改區間查詢(當然還有區間修改單點查詢),如果一道題中只有區間查詢,那麼建議使用字首和維護
思想直接理解不好理解,借助資料
a陣列下標12
3456
78數值2
5632
714以上是我們要儲存的a陣列,就是原資料
b陣列下標12
3456
78數值2
76162
9126以上是操作完的樹狀陣列,探索規律
這張圖是翻部落格上的,博主說是從網上找的,所以也就不標明出處了,很優美的一張圖
用樹狀陣列的形式表示出來即為上圖(上圖指第二張)
也就是說,b陣列負責維護一段a陣列的區間和
這裡引入乙個lowbit函式 ,lowbit(a)表示a的二進位制格式下最後乙個1表示的數
十進位制數
二進位制數
lowbit值
1000112
001023
001114
010045
010116
011027
011118
1000
8………
結合之前的圖,我們可以發現,當a+lowbit(a)=b時,a就會包括在b維護的這段區間和中,若b+lowbit(b)=c,那麼a,b就都包括在c所維護的區間和中,樹狀陣列的各種操作均通過這個性質來進行
接下來直接結合**實現吧
幾種常用函式:
lowbit
int lowbit(int x)//求x的lowbit值
單點修改
int modify(int p,int c)//給p加上c
建立樹狀陣列(其實就是n次單點修改)
for (int i=1;i<=n;i++)
modify(i,a[i]);
區間查詢(其實就是求字首和)
int query(int l)//求1~l的字首和
附例題 洛谷 3374 【模板】樹狀陣列 1
#include#define maxn 500050
using namespace std;
int n,m;
int a[maxn],b[maxn];
int lowbit(int x)
int modify(int x,int y)
int query(int x)
int main()
if (p==2)
}return 0;
}
樹狀陣列(單點修改區間查詢)
lowbit是用來取出二進位制中最低位數的1所代表的二進位制的值。只需要記下 就行了 int lowbit int x 將乙個樹的最子節點修改,則其父節點也需要更改,父父節點也需要修改。x x lowbit x 就是用來取出其父節點的。void add int x,int k 能查詢原陣列的字首和,...
樹狀陣列 單點修改,區間查詢
本人水平有限,題解不到為處,請多多諒解 本蒟蒻謝謝大家 題目 time limit 10 sec memory limit 512 mb submit 231 solved 78 submit status web board 給定數列 a 1 a 2 a n 你需要依次進行 q個操作,操作有兩類 ...
樹狀陣列 1 單點修改,區間查詢
這是一道模板題。給定數列 a 1 a 2 a n 你需要依次進行 q 個操作,操作有兩類 1 i x 給定 i,x,將 a i 加上 x 2 l r 給定 l,r,求 ri la i 的值 換言之,求 a l a l 1 a r 的值 第一行包含 2 個正整數 n,q,表示數列長度和詢問個數。保證 ...