It is the path you have chosen. Take pride in it. Kotomine Kirei

GldHkkowo

[树状数组]模板

【模板】树状数组

题目描述

如题,已知一个数列,你需要进行下面两种操作:

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 }

 

 

posted on 2018-04-15 15:58  GldHkkowo  阅读(111)  评论(0编辑  收藏  举报

导航