差分(1)——差分数组

写这个博客主要的原因是解释另一道题运输计划的树上差分,另外也是记录一下,不然每次都以为差分好难,其实是非常容易的。

差分的定义:

我们先看看如下的数列 a a a

1 5 6 7 4 3 2

那么假设我们需要区间修改这个数列多次,但最后只求一个数a[3]。
如果我们每次都改区间的和,那么我们必然会浪费大量时间,如果数据变大就会很慢。
想用前缀和?多次维护,只求一次,这样也没什么用呀!

那么我们只能用差分了!

就比如上面的这串数字,我们用一个数组 c f cf cf存, c f [ i ] cf[i] cf[i]代表 a [ i ] a[i] a[i] a [ i − 1 ] a[i-1] a[i1]位的数大 c f [ i ] cf[i] cf[i](如果 a [ i ] < a [ i − 1 ] a[i]<a[i-1] a[i]<a[i1] c f [ i ] cf[i] cf[i]将会是负数),即两数之差。那么很明显,初始的 c f [ i ] cf[i] cf[i]只要在读入时将 a [ i ] − a [ i − 1 ] a[i]-a[i-1] a[i]a[i1]存入即可。( c f [ 1 ] cf[1] cf[1]就是 a [ 1 ] a[1] a[1],因为 a [ 1 ] − a [ 0 ] ( a [ 0 ] = 0 ) = a [ 1 ] a[1]-a[0](a[0]=0)=a[1] a[1]a[0]a[0]=0=a[1]

如何求a[i]?

a [ i ] a[i] a[i]只要求出 c f [ 1 ] + c f [ 2 ] + c f [ 3 ] + . . . + c f [ i ] cf[1]+cf[2]+cf[3]+...+cf[i] cf[1]+cf[2]+cf[3]+...+cf[i]就可以了。

如何修改区间?

那如果我要把 x . . . y x...y x...y这个区间加 z z z怎么办?我们只要在 c f [ x ] cf[x] cf[x] + z +z +z(代表 a [ x ] . . . a [ n ] a[x]...a[n] a[x]...a[n]都+1),再在 c f [ y + 1 ] cf[y+1] cf[y+1]处-1(代表 a [ y + 1 ] . . . a [ n ] a[y+1]...a[n] a[y+1]...a[n] − z -z z)。

这样就做到 a [ x ] . . . a [ y ] + z a[x]...a[y]+z a[x]...a[y]+z了:
差分(1)——差分数组_第1张图片
欢迎看到下一期差分(1)——差分数组(待更)。

你可能感兴趣的:(差分)