差分的基本介绍


差分算法是一种常用的算法技巧,用于将一个序列的某个区间上的元素进行修改。差分算法可以在 O(1) 的时间内修改一个区间上的所有元素,并在 O(N) 的时间内将差分数组转换为原始序列。以下是差分算法的详细解释:

差分

首先,我们需要定义一个差分数组 diff,它的长度和原始序列相同。diff[i] 表示原始序列中第 i 个元素与第 i-1 个元素之间的差值。也就是说,diff[i] = nums[i] - nums[i-1]。我们可以把 diff 看做是一个记录每个元素与前一个元素之间差值的数组。

构造(O(n))

n = int(input())
a = [0]+list(map(int, input().split()))
d = [a[i+1]-a[i] for i in range(n)]

a要填上0的原因:为了保证有d[1]=a[1]-a[0]=a[1],保证后面累加时能消掉,也保证了数的位置和下标(索引)的一致性。

d这里为了方便而和a错开了一位,变成了d[i]=a[i+1]-a[i],如果不习惯可以在d前面补个零

区间修改(O(1))

因为整个区间都同时做出某种修改,那么区间内的nums[i]-nums[i-1]就不变,即d[i]不变。这样就只有区间的两端变了,比如[1, 3](索引)都+1,那么diff[1]=diff[left]=nums[1]-nums[0]就会+1,diff[4]=diff[right+1]=nums[4]-nums[3]就会-1。

假设我们需要对原始序列中的区间 [left, right] 上的元素进行加上一个值 val 的操作。我们可以通过修改差分数组来实现这个操作。具体来说,我们可以将 diff[left] 加上 val,而将 diff[right+1] 减去 val。这样,我们就成功地将对原始序列的区间修改操作,转换成了对差分数组的两个单点修改操作。可以看出,这种修改方式的时间复杂度是 O(1) 的。

单点查询(O(L))

q = int(input())
print(sum([b[i] for i in range(q)]))

比如查询a[3], a [ 3 ] = ( a [ 3 ] − a [ 2 ] ) + ( a [ 2 ] − a [ 1 ] ) + ( a [ 1 ] − a [ 0 ] ) = ∑ i = 0 2 b [ i ] a[3] = (a[3]-a[2])+(a[2]-a[1])+(a[1]-a[0]) = \sum^2_{i=0}b[i] a[3]=(a[3]a[2])+(a[2]a[1])+(a[1]a[0])=i=02b[i]

用途

差分算法常用于解决一些需要对序列中的某个区间进行修改的问题,如区间加、区间减、区间求和等问题。在一些情况下,差分算法也可以用来解决离线查询问题,比如离线计算序列中每个位置的前缀和。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈子昂-北工大

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值