线段树求和

  线段树如下图所示,是一个二叉搜索树,记录了a到b的一些信息,比如在这里我们记录a到b所有节点数的总和。下图所示:根节点是1-4,这个节点可以分为1-2,3-4两个子节点,同理,子节点继续往下面分裂。

例题:

在示例代码中,

1.a数组存放这个线段树,每个节点的父节点(加)或它前面的兄弟节点(减,有时候找不到,直接找到0,就是没有)可以通过lowbit计算

  具体展开关系:1->2;2->4;3->4;4->8;5->6;6->8;7->8;

2.lowbit:

  正数与它的负数的与,负数的二进制是正数取反再加一

 3.getsum

  获取0-t的总和,8(4)记录了0-8的所有值,所以直接可求

  7:记录了自己,所以要计算6(记录了5-6),4(0-4)

 4.代码贴在这主要为了遇到的时候快速复制粘贴

#include <stdio.h>
#include <string.h>
#include<math.h>
int a[50005];
int n;
int lowbit(int t){
	return t&(-t);
}
void insert(int t,int d){
	while(t<=n){
		a[t]+=d;
		t=t+lowbit(t);
	}
}
__int64 getsum(int t){
	__int64 sum=0;
	while(t>0){
		sum+=a[t];
		t=t-lowbit(t);
	}
	return sum;
}
int main(){
	int T,i,j,k,t;
	scanf("%d",&T);
	t=0;
	while(T--){
		memset(a,0,sizeof(a));
		scanf("%d",&n);
		for(i=1;i<=n;i++){
			scanf("%d",&k);
			insert(i,k);
		}
		char str[10];
		scanf("%s",str);
		printf("Case %d:\n",++t);
		while(strcmp(str,"End")!=0){
			int x,y;
			scanf("%d%d",&x,&y);
			if(strcmp(str,"Query")==0)
				printf("%lld\n",getsum(y)-getsum(x-1));
			else if(strcmp(str,"Add")==0)
				insert(x,y);
			else if(strcmp(str,"Sub")==0)
				insert(x,-y);
			scanf("%s",str);
		}
	}
	return 0;
}

  

转载于:https://www.cnblogs.com/zhengyuqian/p/10524728.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值