P3374 【模板】树状数组 1
【单点修改,区间查询】
题意
【模板】树状数组 1
题目描述
如题,已知一个数列,你需要进行下面两种操作:
-
将某一个数加上 \(x\)
-
求出某区间每一个数的和
输入格式
第一行包含两个正整数 \(n,m\),分别表示该数列数字的个数和操作的总个数。
第二行包含 \(n\) 个用空格分隔的整数,其中第 \(i\) 个数字表示数列第 \(i\) 项的初始值。
接下来 \(m\) 行每行包含 \(3\) 个整数,表示一个操作,具体如下:
-
1 x k含义:将第 \(x\) 个数加上 \(k\) -
2 x y含义:输出区间 \([x,y]\) 内每个数的和
输出格式
输出包含若干行整数,即为所有操作 \(2\) 的结果。
样例 #1
样例输入 #1
5 5
1 5 4 2 3
1 1 3
2 2 5
1 3 -1
1 4 2
2 1 4
样例输出 #1
14
16
提示
【数据范围】
对于 \(30\%\) 的数据,\(1 \le n \le 8\),\(1\le m \le 10\);
对于 \(70\%\) 的数据,\(1\le n,m \le 10^4\);
对于 \(100\%\) 的数据,\(1\le n,m \le 5\times 10^5\)。
数据保证对于任意时刻,\(a\) 的任意子区间(包括长度为 \(1\) 和 \(n\) 的子区间)和均在 \([-2^{31}, 2^{31})\) 范围内。
样例说明:

故输出结果14、16
解析
单点修改,区间查询 模板题
代码
#include<bits/stdc++.h>
using namespace std;
const int N = 5e5 + 10;
int tr[N],n,m;
int lowbit(int x){
return x & -x;
}
void add(int x,int k){
while(x <= n){
tr[x] += k;
x = x + lowbit(x);
}
}
int sum(int x){
int ans = 0;
while(x >= 1){
ans += tr[x];
x = x - lowbit(x);
}
return ans;
}
int main(){
scanf("%d %d",&n,&m);
for(int i=1,x;i<=n;i++){
scanf("%d",&x);
add(i,x);
}
while(m--){
int op,x,y;
scanf("%d %d %d",&op,&x,&y);
if(op == 1){
add(x,y);
}else{
printf("%d\n",sum(y) - sum(x-1));
}
}
return 0;
}
浙公网安备 33010602011771号