[树状数组]模板
【模板】树状数组
题目描述
如题,已知一个数列,你需要进行下面两种操作:
1.将某一个数加上x
2.求出某区间每一个数的和
输入
输入格式:
第一行包含两个整数N、M,分别表示该数列数字的个数和操作的总个数。
第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值。
接下来M行每行包含3或4个整数,表示一个操作,具体如下:
操作1: 格式:1 x k 含义:将第x个数加上k
操作2: 格式:2 x y 含义:输出区间[x,y]内每个数的和
输出
输出格式:
输出包含若干行整数,即为所有操作2的结果。
样例输入
5 5
1 5 4 2 3
1 1 3
2 2 5
1 3 -1
1 4 2
2 1 4
样例输出
14
16
提示
对于30%的数据:N<=8,M<=10
对于70%的数据:N<=10000,M<=10000
对于100%的数据:N<=500000,M<=500000
代码:
1 #include<cstdio> 2 const int Maxv = 500005; 3 4 int sum[Maxv], n; 5 6 int lowbit(int x) { 7 return x & (-x); 8 } 9 10 int getsum(int x) { 11 int ans = 0; 12 for (int i = x; i > 0; i -= lowbit(i)) { 13 ans += sum[i]; 14 } 15 return ans; 16 } 17 18 void add(int x, int y) { 19 for (int i = x; i <= n; i += lowbit(i)) { 20 sum[i] += y; 21 } 22 return; 23 } 24 25 int main() { 26 int m; 27 scanf("%d%d", &n, &m); 28 for (int i = 1; i <= n; i++) { 29 int tmp; 30 scanf("%d", &tmp); 31 add(i, tmp); 32 } 33 while(m--) { 34 int t, x, y; 35 scanf("%d%d%d", &t, &x, &y); 36 if (t == 1) { 37 add(x, y); 38 } 39 else { 40 printf("%d\n", getsum(y) - getsum(x - 1)); 41 } 42 } 43 return 0; 44 }