title

树状数组

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;
}
posted @ 2018-09-10 01:29  Horrigue_JyowYang  阅读(75)  评论(0编辑  收藏  举报