树状数组,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 【模板】樹狀數(shù)組 1
題目描述
如題,已知一個數(shù)列,你需要進(jìn)行下面兩種操作:
1.將某一個數(shù)加上x
2.求出某區(qū)間每一個數(shù)的和
輸入輸出格式
輸入格式:第一行包含兩個整數(shù)N、M,分別表示該數(shù)列數(shù)字的個數(shù)和操作的總個數(shù)。
第二行包含N個用空格分隔的整數(shù),其中第i個數(shù)字表示數(shù)列第i項的初始值。
接下來M行每行包含3或4個整數(shù),表示一個操作,具體如下:
操作1: 格式:1 x k 含義:將第x個數(shù)加上k
操作2: 格式:2 x y 含義:輸出區(qū)間[x,y]內(nèi)每個數(shù)的和
輸出格式:輸出包含若干行整數(shù),即為所有操作2的結(jié)果。
?
?
代碼:
1 /* P3374 【模板】樹狀數(shù)組 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 【模板】樹狀數(shù)組 2
題目描述
如題,已知一個數(shù)列,你需要進(jìn)行下面兩種操作:
1.將某區(qū)間每一個數(shù)數(shù)加上x
2.求出某一個數(shù)的和
輸入輸出格式
輸入格式:第一行包含兩個整數(shù)N、M,分別表示該數(shù)列數(shù)字的個數(shù)和操作的總個數(shù)。
第二行包含N個用空格分隔的整數(shù),其中第i個數(shù)字表示數(shù)列第i項的初始值。
接下來M行每行包含2或4個整數(shù),表示一個操作,具體如下:
操作1: 格式:1 x y k 含義:將區(qū)間[x,y]內(nèi)每個數(shù)加上k
操作2: 格式:2 x 含義:輸出第x個數(shù)的值
輸出格式:輸出包含若干行整數(shù),即為所有操作2的結(jié)果。
?
?
數(shù)據(jù)直接 modify 到差分?jǐn)?shù)組里,方便區(qū)間修改和單元素查詢(原本樹狀數(shù)組作用是方便單元素修改和區(qū)間查詢 )。
代碼:
1 /* P3368 【模板】樹狀數(shù)組 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 }?
轉(zhuǎn)載于:https://www.cnblogs.com/greyqz/p/7199382.html
總結(jié)
以上是生活随笔為你收集整理的树状数组,Fenwick Tree的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 笔趣阁app如何免广告
- 下一篇: 按钮随复选框选中与取消变换样式