树状数组(改点求段) ,洛谷之提高历练地,提高模板-nlogn数据结构

正文

      这题知道树状数组的肯定秒打咯~

     我们首先要清楚lowbit(x)这个数组的含义,指的是,x最后的一个1及其后面的0组成的二进制数。如lowbit(1001001101100(2))=100(2)=4lowbit(1010101101010000(2))=10000(2)=16;

      所以我们可以肯定的是lowbit一定是一个2的幂次方数。

      在树状数组里面表示的就是x管理着(x-lowbit(x)+1)~x这段区间的数,而掌管着他的正好就是掌管

      所以我们每次从当前的位置往上更新即可。

#include
#include
#include

int n,m;
long long tot[500010];

int lowbit(int x){//你没看错就是这么简单,不懂的去学学补码~
	return x&(-x);
}

void add(int x,int t){
	while(x<=n){
		tot[x]+=t;
		x+=lowbit(x);
	}
}

long long get_tot(int x){
	long long t=0;
	while(x>=1){//get的时候就直接向自己的上一棵不包含的树移动
		t+=tot[x];
		x-=lowbit(x);
	}
	return t;
}

int main(){
	scanf("%d %d",&n,&m);
	for(int i=1;i<=n;i++){
		int x;
		scanf("%d",&x);
		add(i,x);
	}
	for(int i=1;i<=m;i++){
		int t,x,y;
		scanf("%d %d %d",&t,&x,&y);
		if(t==1) add(x,y); 
		else printf("%lld\n",get_tot(y)-get_tot(x-1));
	}
}

你可能感兴趣的:(树状数组(改点求段) ,洛谷之提高历练地,提高模板-nlogn数据结构)