树状数组可以有两类操作
1.区间查询和点修改
2.区间修改和点查询
这两种操作的本质差别就是,tree数组的意义不同。在1中,tree数组是储存的区间和,2中,tree数组储存的是一个差分数组。这道题是用的2
如果tree数组是一个差分数组,那么Σtree i = a[i],且区间修改只需要update(x,k)和update(y+1,-k)。
注意,tree[1]=a[1],作为初项,才能满足上面两个对应关系
#include<bits/stdc++.h>
#define maxn 500005
#define lowbit(x) ((x)&(-x))
typedef long long ll;
using namespace std;
ll tree[maxn]={0};
int n,m;
void aupdate(ll x, ll k){
while(x<=n){
tree[x]+=k;
x+=lowbit(x);
}
}
ll summ(ll x){
ll ans=0;
while(x!=0){
ans+=tree[x];
x-=lowbit(x);
}
return ans;
}
ll query(ll x,ll y){
return summ(y)-summ(x-1);
}
int main(void){
cin>>n>>m;
ll temp=0;
for(int i=1;i<=n;i++){
ll ai;
scanf("%lld",&ai);
aupdate(i,ai-temp);
temp=ai;
}
while(m--){
int op;
ll x,y,k;
scanf("%d",&op);
switch(op){
case 1:
scanf("%lld%lld%lld",&x,&y,&k);
// for(ll i=x;i<=y;i++){
// aupdate(i,k);
// }
aupdate(x,k);
aupdate(y+1,-1*k);
// tree[x]+=k;
// tree[y]+=k;
break;
case 2:
scanf("%lld",&x);
printf("%lld\n",query(1,x));
break;
default:
break;
}
}
}