树状数组模板程序讲解2(超详细)

本文详细介绍了树状数组在区间修改和单点查询方面的应用,提供模板代码,并引用了相关题目链接。文章建议读者掌握差分思想,以辅助理解,并附带图形帮助理解程序逻辑。此外,还鼓励读者通过留言或寻找其他教程解决疑问。
摘要由CSDN通过智能技术生成

本文主要介绍和解释树状数组的区间修改单点查询的模板
区间修改和单点查询请看树状数组模板程序讲解1(超详细)

模板题目:

模板代码:


本题需要用到差分思想,如果不会可以先在这里学习,否则很难理解本题做法(而且差分经常和树状数组一起出现)


为了方便你对程序的理解,可以在不太清楚的地方结合此图思考一下,能节约思考时间。

讲解请看代码注释

#include<iostream>
#include<cstdio>
#define reint register int
using namespace std;
int f[2000001],n,b[2000001]; //f用来维护差分数组的前缀和(也就是记录每一次修改对原数组造成的影响),b是数组初始数值
int lowbit(int a) {  //lowbit函数,用来计算a在二进制下从右往左第一个`1`出现的位置(其实说白了就是用来跳转到f中和a有关的变量,实在不懂记住就可以,不用在这里浪费时间)
	return a&-a;   //计算方法,等同于a&(a^(a-1))
}
void add(int x,int k) {  //把第x个数加上k
	while(x<=n) {   //如果没有越界就一直循环
		f[x]+=k;  //把第x个数加上k
		x+=lowbit(x);  //跳转代码,快速找到包含了f[x]的所有前缀和
	}
	return;
}
int sum(int x) {  //用来计算差分数组的前缀和
	int ans(0);   //累加变量
	while(x>0) {   //如果没有越界就一直循环
		ans+=f[x];    //累加前缀和
		x-=lowbit(x);   //lowbit跳转
	}
	return ans;  //返回ans
}
int main() {
	int i,m;
	cin>>n>>m;
	for(i=1; i<=n; ++i) {
		scanf("%d",&b[i]);  //输入初始数据
	}
	for(i=1; i<=m; ++i) {
		int p,x,y,z;
		scanf("%d",&p);
		if(p==1) {
			scanf("%d%d%d",&x,&y,&z);
			add(x,z);  //差分思想,具体见上面链接
			add(y+1,-z);  //差分思想
		} else {
			scanf("%d",&x);
			printf("%d\n",sum(x)+b[x]);  //用多次修改后造成的影响+数组初始值就是改变后的值
		}
	}
}

如果还有其他问题可以在下方留言,也可以在这里寻找其他更适合适合你的教程~

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值