树状数组,Fenwick Tree
Fenwick Tree, (also known as Binary Indexed Tree,二叉索引樹), is a high-performance data structure to calculate the sum of elements from the beginning to the indexed in a array.
?
It needs three functions and an array:
- Array sum; It stores the data of Fenwick Tree.
- int lowbit(int); To get the last 1 of the binary number. 取出最低位 1
- void modify(int, int); To modify the value of an element, the second input "val" is the value that would be added.
- int query(int); To get the sum of elements from the beginning to the indexed.
?
How to get the last 1 of a binary number? Use AND operating:? x & (-x).
?
Definitions:
int sum[N];inline int lowbit(int x) {return x & (-x); } inline void modify(int x, int val) {while (x <= n) {d[x] += val; x += lowbit(x);} } inline int query(int x) {int sum = 0;while (x > 0) {sum += d[x]; x -= lowbit(x);}return sum; }?
?
例題1:洛谷P3374 【模板】樹狀數組 1
題目描述
如題,已知一個數列,你需要進行下面兩種操作:
1.將某一個數加上x
2.求出某區間每一個數的和
輸入輸出格式
輸入格式:第一行包含兩個整數N、M,分別表示該數列數字的個數和操作的總個數。
第二行包含N個用空格分隔的整數,其中第i個數字表示數列第i項的初始值。
接下來M行每行包含3或4個整數,表示一個操作,具體如下:
操作1: 格式:1 x k 含義:將第x個數加上k
操作2: 格式:2 x y 含義:輸出區間[x,y]內每個數的和
輸出格式:輸出包含若干行整數,即為所有操作2的結果。
?
?
代碼:
1 /* P3374 【模板】樹狀數組 1 2 * Au: GG 3 */ 4 #include <cstdio> 5 #include <cstdlib> 6 #include <cstring> 7 #include <cmath> 8 #include <ctime> 9 #include <iostream> 10 #include <algorithm> 11 using namespace std; 12 const int N = 500000 + 3; 13 int n, m, d[N]; 14 15 inline int lowbit(int x) { 16 return x & (-x); 17 } 18 inline void modify(int x, int val) { 19 while (x <= n) { 20 d[x] += val; x += lowbit(x); 21 } 22 } 23 inline int getsum(int x) { 24 int sum = 0; 25 while (x > 0) { 26 sum += d[x]; x -= lowbit(x); 27 } 28 return sum; 29 } 30 31 int main() { 32 scanf("%d%d", &n, &m); 33 for (int i = 1, w; i <= n; i++) { 34 scanf("%d", &w); modify(i, w); 35 } 36 while (m--) { 37 int o, x, y; 38 scanf("%d%d%d", &o, &x, &y); 39 if (o == 1) modify(x, y); 40 if (o == 2) printf("%d\n", getsum(y) - getsum(x - 1)); 41 } 42 return 0; 43 }?
?
例題2:洛谷P3368 【模板】樹狀數組 2
題目描述
如題,已知一個數列,你需要進行下面兩種操作:
1.將某區間每一個數數加上x
2.求出某一個數的和
輸入輸出格式
輸入格式:第一行包含兩個整數N、M,分別表示該數列數字的個數和操作的總個數。
第二行包含N個用空格分隔的整數,其中第i個數字表示數列第i項的初始值。
接下來M行每行包含2或4個整數,表示一個操作,具體如下:
操作1: 格式:1 x y k 含義:將區間[x,y]內每個數加上k
操作2: 格式:2 x 含義:輸出第x個數的值
輸出格式:輸出包含若干行整數,即為所有操作2的結果。
?
?
數據直接 modify 到差分數組里,方便區間修改和單元素查詢(原本樹狀數組作用是方便單元素修改和區間查詢 )。
代碼:
1 /* P3368 【模板】樹狀數組 2 2 * Au: GG 3 */ 4 #include <cstdio> 5 #include <cstdlib> 6 #include <cstring> 7 #include <cmath> 8 #include <ctime> 9 #include <iostream> 10 #include <algorithm> 11 using namespace std; 12 const int N = 500000 + 3; 13 int n, m, d[N]; 14 15 inline int lowbit(int x) { 16 return x & (-x); 17 } 18 inline void modify(int x, int val) { 19 while (x <= n) { 20 d[x] += val; x += lowbit(x); 21 } 22 } 23 inline int getsum(int x) { 24 int sum = 0; 25 while (x > 0) { 26 sum += d[x]; x -= lowbit(x); 27 } 28 return sum; 29 } 30 31 int main() { 32 scanf("%d%d", &n, &m); 33 for (int i = 1, w, v = 0; i <= n; i++) { 34 scanf("%d", &w); modify(i, w - v); v = w; 35 } 36 while (m--) { 37 int o, x, y, k; 38 scanf("%d%d", &o, &x); 39 if (o == 1) { 40 scanf("%d%d", &y, &k); 41 modify(x, k); modify(y + 1, -k); 42 } 43 if (o == 2) printf("%d\n", getsum(x)); 44 } 45 return 0; 46 }?
轉載于:https://www.cnblogs.com/greyqz/p/7199382.html
總結
以上是生活随笔為你收集整理的树状数组,Fenwick Tree的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 笔趣阁app如何免广告
- 下一篇: lol云顶之奕六枪手配什么 LOL新手适
