前缀和+差分数组

20 篇文章 0 订阅
4 篇文章 0 订阅

总结背景

在写CSP的时候发现有一段时间第二题非常喜欢考这个考点,在这里总结一些

前缀和

概念

  1. 前缀和是什么:数组该位置之前的元素之和
  2. 作用:快速求出数组中某段区间的和
    如果每次都是遍历一遍求和那就每次都得是O(n)的复杂度,m次就得到O(mn)。如果用前缀和,那就第一遍用O(n)的复杂度遍历求出前缀和,然后每次求的的时候只需要区间首位作差即可,这个时候每次复杂度就降到O(1)啦
  • 所以在说方法之前在强调一下使用场景
    一般经常需要求一个连续区间的和的时候常常使用前缀和来提高效率

方法

一维数组的前缀和

求一维数组a中(l,r)区间的和,可以首先求出前缀和数组s,然后使用s[r]-s[l-1]可以快速求出区间的和

  1. 求前缀和公式:s[i]=s[i-1]+a[i]
  2. 求区间(l,r)的和公式:区间和m=s[r]-s[l-1]
a = [0]+list(map(int,input().split()))
s = [0]*n
# 这里从0开始,但是一般可以使数组从1开始,这样可以简化计算
for i in range(1,n):
	s[i] = s[i-1]+a[i]

# 求区间范围
def get_part_sum(l,r):
	return s[r]-s[l-1]

二维数组的前缀和

CSP大多用的是一维数组,二维数组的使用和一维数组类似,这里就先不写二维数组啦

差分数组

差分数组在一定程度上是前缀和的逆运算
差分数组实际上就是记住当前数据相对于前一个数据的变化量,这样如果要对一个区间内所有的数据都加或减相同的数时,只需要对始末进行处理,而不需要每次处理都要遍历数组,只在最后求结果时遍历一次输出即可

用代码理解一下:

# a:原数组
# b:差分数组
b[1] = a[1]
for i in range(2,n):
	b[i] = a[i]-a[i-1]

核心操作:
将区间(l,r)全部加上C,等价于:b[l]+=C, b[r+1]-=C

理解:区间的开头b[l]加上C后,求区间里每一个数时从区间开始处进行累加,此时每一个数都加了C;然而+C只进行到了b[r],b[r+1]没有进行+C操作,累加到r+1时还会加C,所以要在r+1处进行-C操作

来段代码理解一下:

# a:原始数组
# b:差分数组
def create_b():
	for i in range(1,n+1):
		b[i] = a[i]-a[i-1]
	return b
def edit_arr(l,r,c):
	b[l]+=c
	b[r+1]-=c
def get_new_num(index):
	new_num = 0
	for i in range(1,index):
		new_num += b[i]
	return new_num
	

例题

CSP

202203-4 出行计划
201312-3 最大的矩形
202109-2 非零段划分

leetcode

这里还没有具体做,先参考一下大佬的记录

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值