【树状数组】区间修改,单点查询 洛谷P3368

【树状数组】单点修改,区间查询 洛谷P3374_搂鱼114514的博客-CSDN博客

P3368 【模板】树状数组 2 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

题意

接上一篇题解,这一题由“单点修改,区间查询”变成了“区间修改,单点查询”。

思路

此时我们要引入一个知识点:差分

差分数组cha,使得cha_i=a_i-a_{i-1},其中a_0=cha_0=0

那么不难发现,a_i=\sum_{i\rightarrow n}^{i=1}cha_i

差分数组的一个性质:对一个区间增减某个值的时候,差分数组的区间左端点值会同步变化,而其右端点后一个值会产生相反地变化,其他点不变。因此在更新区间[x,y]时,x增加k那么y+1就要相反的减去k

void addpoint(ll x,ll k)
{
	for(int i=x;i<=n;i+=lowbit(i))
	a[i]+=k;
}
······
    cin>>x>>y>>k;
    addpoint(x,k);
	addpoint(y+1,-k);

a_i只需要将差分数组的前i个值相加

ll chaxun(ll y)
{
	ll ans=0;
	for(int i=y;i>=1;i-=lowbit(i))
	ans+=a[i];
	return ans;
}

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll z=5000005;
ll n,m,zt,x,y,a[z],k,c[z],cha;
void fastread()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
}
ll lowbit(ll x)
{
	return x&(-x);
}
void addpoint(ll x,ll k)
{
	for(int i=x;i<=n;i+=lowbit(i))
	a[i]+=k;
}
ll chaxun(ll y)
{
	ll ans=0;
	for(int i=y;i>=1;i-=lowbit(i))
	ans+=a[i];
	return ans;
}
int main()
{
	fastread();
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		cin>>c[i];
		cha=c[i]-c[i-1];
		addpoint(i,cha);
	}
	for(int i=1;i<=m;i++)
	{
		cin>>zt;
		if(zt==1)
		{
			cin>>x>>y>>k;
			addpoint(x,k);
			addpoint(y+1,-k);
		}
		if(zt==2)
		{
			cin>>x;
			cout<<chaxun(x)<<endl;
		}
	}
	return 0;
} 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值