题目描述
这是LibreOJ上的树状数组模板题,这个题考查的点是单点修改和区间查询。在此附上一版我的AC代码:
#include<iostream>
using namespace std;
typedef long long ll;//这个题必须用int会爆。
ll n, q;
ll a[1000000+10];//a是原数组
ll c[1000000+10];//b是维护a的树状数组。
ll lowbit(ll x)
{
return x & -x;
}
void creat(){
for(ll i=1;i<=n;i++){
c[i]+=a[i];
ll j=i+lowbit(i);
if(j<=n) c[j]+=c[i];
}
}
//建树函数。
void add(ll x, ll k){
while(x<=n){
c[x]+=k;
x+=lowbit(x);
}
}
//单点修改函数。
ll getsum(ll x){
ll sum=0;
while(x>=1){
sum+=c[x];
x-=lowbit(x);
}
return sum;
}
//求前x项和函数.
int main()
{
scanf("%lld%lld", &n,&q);
for(ll i=1;i<=n;i++){
scanf("%lld", &a[i]);
}
creat();
ll flag, a, b;
for(ll i=1;i<=q;i++){
scanf("%lld%lld%lld", &flag, &a, &b);
if(flag==1) {
add(a,b);
} else if(flag==2){
ll sumda, sumxiao;
sumda = getsum(b);
sumxiao = getsum(a-1);
sumda-=sumxiao;//区间和可以看做是俩个前缀和的差。
printf("%lld\n", sumda);
}
}
return 0;
}