树状数组
1、区间查单点加
#include<cstdio>
#include<cctype>
using namespace std;
const int N =500010;
int n,m,a[N],c[N];
inline int read(){
int f=0,x=0;
char ch=getchar();
while(!isdigit(ch)) f|=(ch=='-'),ch=getchar();
while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return f?-x:x;
}
inline int lowbit(int x){
return x&(-x);
}
inline void gettree(){
for(register int i=1;i<=n;++i)
for(register int j=i-lowbit(i)+1;j<=i;++j)
c[i]+=a[j];
}
inline void modify(int x,int val){
for(;x<=n;x+=lowbit(x)) c[x]+=val;
}
inline int query(int l,int r){
int s=0,ss=0;
--l;
for(;l;l-=lowbit(l)) s+=c[l];
for(;r;r-=lowbit(r)) ss+=c[r];
return ss-s;
}
signed main(){
n=read(),m=read();
for(register int i=1;i<=n;++i) a[i]=read();
gettree();
for(register int i=1,jud,x,y;i<=m;++i){
jud=read(),x=read(),y=read();
if(jud==1) modify(x,y);
else printf("%d\n",query(x,y));
}
return 0;
}
2、单点查区间加(差分)
#include<cstdio>
#include<cctype>
using namespace std;
const int N =500010;
int n,m,a[N],c[N];
inline int read(){
int f=0,x=0;
char ch=getchar();
while(!isdigit(ch)) f|=(ch=='-'),ch=getchar();
while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return f?-x:x;
}
inline int lowbit(int x){
return x&(-x);
}
inline void gettree(){
for(register int i=1;i<=n;++i)
for(register int j=i-lowbit(i)+1;j<=i;++j)
c[i]+=a[j];
}
inline void update(int x,int val){
for(;x<=n;x+=lowbit(x)) c[x]+=val;
}
inline int check(int x){
int s=0;
for(;x;x-=lowbit(x)) s+=c[x];
return s;
}
signed main(){
n=read(),m=read();
for(register int i=1;i<=n;++i) a[i]=read();
for(register int i=n;i;--i) a[i]-=a[i-1];//差分
gettree();
for(register int i=1,jud,x,y,k;i<=m;++i){
jud=read(),x=read();
if(jud==1){
y=read(),k=read();
update(x,k),update(y+1,-k);
} else printf("%d\n",check(x));
}
return 0;
}