一维差分的实现

        这是C++算法基础-基础算法专栏的第十三篇文章,专栏详情请见此处


引入

        上次我们学习了前缀和的实现,它可以快速解决求区间和问题。这次我们要学习差分,它是前缀和的逆运算,可以快速解决对序列的一个区间同时加或减一个数这样的问题。

        对序列的一个区间加或减一个数,它的朴素做法时间复杂度为O(n) ,而用差分做法就可以将时间复杂度优化为O(1)

        下面我们就来讲一维差分的实现。

定义

        差分是一种和前缀和相对的策略,可以当做是求和的逆运算。

过程

        表示

        对于原数组a,我们尝试构造一个数组b,使得数组a为数组b的前缀和数组,即a\left [ i \right ]=b\left [ 1 \right ]+b\left [ 2 \right ]+\cdots +b\left [ i \right ],也就是说,a_{x}=\sum_{i=1}^{x}b_{i},这时,我们就把数组b称为数组a差分数组

        赋值

        那如何构造这个数组b呢?

        我们令b\left [ 1 \right ]=a\left [ 1 \right ]b\left [ i \right ]=a\left [ i \right ]-a\left [ i-1 \right ]。可以看出,b数组每一位的值是a数组中两个相邻元素的差值。于是,我们在输入数组a时同时进行对b的赋值。

        处理区间值

        当我们想将a数组区间\left [ l,r \right ]中的数值都加c,应该怎么去做呢?这里我们用图表加以理解,0表示当前位未计算,1表示当前位已计算。

        首先,图一展示了起始状态,然后,我们将b\left [ l \right ]计入总和(图二),也就是将b\left [ l \right ]\sim b\left [ n \right ]内的数值都加c,但我们并不需要b\left [ r \right ]之后的数计入总和,所以最后将b\left [ r+1 \right ]减去(图三)。

        得出结论: 将a数组区间\left [ l,r \right ]中的数值都加cb\left [ l \right ]+=cb\left [ r+1 \right ]-=c

代码

        下面给出一维差分代码:

表示:a[i]=b[1]+b[2]+...+b[i]
赋值:b[i]=a[i]-a[i-1]
处理:b[l]+=c,b[r+1]-=c

上一篇-二维前缀和的实现    C++算法基础专栏文章    下一篇-二维差分的实现


每周六更新一篇文章,内容一般是自己总结的经验或是在其他网站上整理的优质内容

点个赞,关注一下呗~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值