前缀和及其应用

前缀和,简单来说,你输入了一串数,用s[i]表示a[1]~a[i]的所有元素的和,那么s数组记录的就是a的前缀和。

用前缀和来进行维护可以很好地节约时间复杂度,比如说有一串数,每次给定一个操作,询问一段区间内所有元素和,要求线性做法O(m+n),这时就不能使用两重循环枚举。我们可以使用前缀和,当询问区间l~r时,我们只要输出s[l]-s[r]就可以了。

前缀和同样可以用在矩阵上,如果用f[i][j]来表示从(1,1)到(i,j)之间所有元素的和,这样的话初始化代码就是:

f[i][j] += f[i - 1][j] + f[i][j - 1] - f[i - 1][j - 1];

这样我们在询问一个矩阵中的元素和时,他的计算公式就是

f[i][j] - f[x - 1][j] - f[i][y - 1] + f[x - 1][y - 1];

下面我们来看其他的应用。

例题1:

给定n个数ai,有m次操作,每个操作是给al~ar增加一个数k。最终输出操作完后的这n个数的值。要求一个O(n+m)的做法。

这种题怎么做呢?如果按最暴力的想法,我们会在每个询问区间内,进行一次循环,但是这样的作法不是线性的,不符合要求。

我们要选择具有代表性的元素来下手,也就是那些发生改变较少的元素。——张浩威

哪些元素的改变比较少呢?我们在一次区间操作之后,区间内的元素都发生了改变,显然不好,我们仔细观察后发现,区间端点与其旁边元素的差值变化比较小。如果在一段区间内+=i,那么就让左端点和其前面的元素的差值+2,右端点和其后面元素的差值-2。这样我们就可以做到线性操作了,只要开一个数组f来记录当前元素和前一个元素的差值即可。

此时我们会发现,a数组其实就是f数组的前缀和!也就是说这道题也可以转换成前缀和来做了。

矩阵的话也大致相同。

对于每次以(x,y)为左上角,(x2,y2)为右下角的矩阵操作,相当于是令s[x][y]+=k,s[x][y2+1]-=k,s[x2+1][y]-=k,s[x2+1][y2+1]+=k。

 

 

 

 

转载于:https://www.cnblogs.com/captain1/p/8424201.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值