题目描述:
如题,已知一个数列,你需要进行下面两种操作:
-
将某一个数加上 x
-
求出某区间每一个数的和
Input
第一行包含两个正整数 n,m,分别表示该数列数字的个数和操作的总个数。
第二行包含 n 个用空格分隔的整数,其中第 i 个数字表示数列第 i 项的初始值。
接下来 m 行每行包含 33 个整数,表示一个操作,具体如下:
-
1 x k
含义:将第 x 个数加上 k -
2 x y
含义:输出区间 [x,y] 内每个数的和
Output
输出包含若干行整数,即为所有操作 22 的结果。
Sample 1
Inputcopy | Outputcopy |
---|---|
5 5 1 5 4 2 3 1 1 3 2 2 5 1 3 -1 1 4 2 2 1 4 | 14 16 |
思路:
这道题考察的是树状数组。
代码:
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
typedef double db;
const int maxn=500005;
int n,m,p,x,y;
ll a,c[maxn];
ll lowbit(int x){
return x&-x;
}
void add(int u,int v){
for(int i=u;i<=n;i+=lowbit(i))
c[i]+=v;
}
ll sum(int u){
int ans=0;
for(int i=u;i>0;i-=lowbit(i))
ans+=c[i];
return ans;
}
int main(){
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%lld",&a);
add(i,a);
}
for(int i=1;i<=m;i++){
scanf("%d%d%d",&p,&x,&y);
if(p==1){
add(x,y);
}
if(p==2){
printf("%lld\n",sum(y)-sum(x-1));
}
}
return 0;
}