树状数组模板
模板(一)
洛谷原题链接
AC代码
#include<bits/stdc++.h>
#define MAXN 2000010
using namespace std;
int n,m,a,e[MAXN];
int q,x,y,k,answ,len;
inline int lb(int o){ //lowbit
return o&(-o);
}
inline void addto(int x,int v){
while(x<=n){
e[x]+=v;
x+=lb(x);
}
}
inline int query(int x){
int ans=0;//因为e[i]中有a[i],所以ans从0开始加
while(x>0){
ans+=e[x];
x-=lb(x);
}
return ans;
}
int main(){
int i,j;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++){
scanf("%d",&a);
addto(i,a); //这里与模板2不同,需要先把初值加入树状数组
}
for(i=1;i<=m;i++){
scanf("%d%d%d",&q,&x,&y);
if(q==1) addto(x,y);
else printf("%d\n",query(y)-query(x-1));
}
return 0;
}
模板(二)
洛谷原题链接
AC代码
#include<bits/stdc++.h>
using namespace std;
int m,n,x,y,k,q;
int a[500010],e[500010];//a[i]是初值,e[i]是累加值(不包含初值)
inline int lb(int o){ //返回o所在区间的长度
return o&(-o);
}
inline void addto(int x,int k){ //给树状数组x之前的值+k
while(x>0){
e[x]+=k;
x-=lb(x);
}
}
inline int query(int x){
int ans=a[x]; //因为e[i]不包含初值,先把初值加进来
while(x<=n){
ans+=e[x];
x+=lb(x);
}
return ans;
}
int main(){
int i,j;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++) scanf("%d",&a[i]);
for(i=1;i<=m;i++){
scanf("%d",&q);
if(q==1){
scanf("%d%d%d",&x,&y,&k);
addto(y,k);
addto(x-1,-k);//先把y之前的+k,再把x-1之前的-k---->给[x,y]+k
}
else{
scanf("%d",&x);
printf("%d\n",query(x));
}
}
return 0;
}