差分使用规范

差分介绍

设数组 data[]={1,6,8,5,10},那么差分数组 different[]={1,5,2,-3,5}
也就是说 different[i]=data[i]-data[i-1] (data[0]=0);

那么 data[i]= ∑ d o w n = 1 i b [ d o w n ] \sum_{down=1}^i b[down] \frac{}{} down=1ib[down]

假如区间[2,4]都加上2的话
此时
data[]={1,8,10,7,10};
different[]={1,7,2,-3,3}

发现 different 数组只有different[2]和different[5]变了,因为区间[2,4]是同时加上2的,所以区间内 different[i]~different[i-1]是不变的

当我们对一个区间[x,y]进行修改的时候,只需要对它的差分数组进行修改,只需要修改 different[x]和different[y+1];

different[x]+=k;different[x]-=k;

例题

由于巨人们的进攻,人类的生活圈已经越来越小。某一年,巨人又开始对南方的围墙发起猛攻,但是南方围墙非常坚固,巨人无法攻进去。不过巨人在某一天感染了一种特殊病毒,这种病毒可以让巨人长高。长高的巨人就可以突破围墙了,这令南方的守城兵长非常恐慌,他不断派人把围墙修改以抵挡敌人的进攻。最后巨人终于停止了这一波攻击。士兵长想知道现在每一堵墙有多高。

输入
第一行两个数n,m表示有n堵围墙,m次修墙

接下来一行n个数为围墙的初始高度。

接下来m行每行3个数Li,Ri,Xi,表示第Li到Ri堵围墙都增高Xi米

输出
一行n个数:第i个数表示编号为i的墙的最后高度。

样例输入
5 2
1 2 3 4 5
1 5 1
2 4 1

样例输出
2 4 5 6 6
【数据范围】
对于30%的数据:1 ≤ n、m ≤ 1000。

对于60%的数据:1 ≤ n、m ≤ 100000。

对于100%的数据:1 ≤ n、m ≤ 700000,1 ≤ Li ≤ Ri ≤ n,1 ≤ Xi ≤ 1000。

#include<cstdio>
#include<iostream>
using namespace std;

typedef unsigned long long ull;
#define digit 700001
ull data[digit],record[digit];
ull length,times;

void enter()
{
	record[0]=0;
	record[length+1]=0;
	
	scanf("%lld%lld",&length,×);
	for(ull i=1;i<=length;i++)
		scanf("%lld",&data[i]),
		record[i]=data[i]-data[i-1];
	
	ull x,y,addsum;
	while(times--)
	{
		scanf("%lld%lld%lld",&x,&y,&addsum);
		record[x]+=addsum;
		record[y+1]-=addsum;
	}
	
	ull sum=0;
	for(ull i=1;i<=length;i++)
	{
		sum+=record[i];
		printf("%lld ",sum);
	}
}

int main()
{
	enter();
	return 0;
}

小结

以后对于区间内加减法并要求输出的题都可以考虑一下 差分算法

关于

感谢 Lyp10000

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值