树状数组的区间修改,单点查询

前段时间处理过树状数组的单点修改,区间查询,那这次来试着搞一搞区间修改,单点查询(对,再下一次就是区间修改区间查询hhh)

首先设定一个a[ ],我们能得到一个与之相对应的差分数组b[ ],使b[i]=a[i]-a[i-1]

原数组a35248
差分数组b32-324

简单可证,a[i]=b[1]+b[2]+....+b[i]

如果我要把2,4的区间中每个数+2

原数组a37468
差分数组b34-32

2

发现没有?b数组只有b[2],b[5] 的值改变了,这个也很好证明的

这样我们就可以用b数组来求a数组啦,1~n求和太慢,于是我们搞一个树状数组优化一下

https://www.luogu.org/problemnew/show/P3368#sub

一道洛谷裸题

以下代码

#include<bits/stdc++.h>
using namespace std;
int a[500010],b[500010],c[500010],n,m;
int lowbit(int x)
{
	return x&-x;
}
void modify(int x,int y)
{
	for (int i=x;i<=n;i+=lowbit(i))
		c[i]+=y;
}
int query(int x)
{
	int ans=0;
	for (int i=x;i>0;i-=lowbit(i))
		ans+=c[i];
	return ans;
}
int main()
{
	cin>>n>>m;
	for (int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
		b[i]=a[i]-a[i-1];
	}
	for (int i=1;i<=n;i++)
		modify(i,b[i]);
	for (int i=1;i<=m;i++)
	{
		int p; 
		cin>>p;
		if (p==1)
		{
			int xx,yy,k;
			cin>>xx>>yy>>k;
			modify(xx,k);
			modify(yy+1,-k);
		}
		if (p==2)
		{
			int k;
			cin>>k;
			printf("%d\n",query(k));
		}
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值