差分
差分
-
题单:差分入门
-
概念:
差分:两个相邻的数之差。
把原数列进行差分,得到新数列,这是1阶差分。
把新数列再差分,得到2阶差分的数列。
以此类推,进行n次差分后,得到的数列就是n阶差分。
应用:
用于解决有规律的区间问题,
例如区间加等差数列,给\(x\in[L,R]\)加上\((x - L) * d\),
2阶差分下的等差数列就可以转化为普通的差分问题\(+1\), \(-1\)。
通常需要找到数列在n阶差分下变成简单差分问题,再进行从\(n\)到\(0\)阶用前缀和还原,还要注意\(n\)阶差分在\(1\)到\(n\)阶的影响要消除。
树上差分:
点权:
对\(u,v\) ,\(+1\);
对\(lca,f(lca)\),\(-1\).
边权:
边记在较深点。
对\(u,v\) ,\(+1\);
对\(lca\),\(-1\).
- 问题:
下面 \(a_{i,j}\) 表示 \(a\) 经过 \(i\) 次差分后第 \(j\) 位的数。
区间对\([L, R]\)加上\(s, ..., e\)的等差数列。
一个等差数列\(y = d(x-1) + s\),容易发现是一次函数,进行一次差分就变成常数,对常数差分就变成\(0\)(\(y''=0\))
原数列\(\{1,2,3,4,5\}\)
一次差分\(\{1,1,1,1,1\}\)
二次差分\(\{1,0,0,0,0\}\)
有操作\([1,3],s=2,e=4\),那么这个等差数列是\(\{2,3,4\}\),公差\(d = 1\)
一次差分得到\(\{2,1,1\}\),这是在一阶差分数组对区间\([1,3]\)加上\(2,1,1\)
在差分得到\(\{2,-1,0\}\),发现就能在原数组的二阶差分下,对\(a_{2,1}+1\),对\(a_{2,2} - 1\)对 \(a_{2,3 + 1} - (2 - 1)\).
二阶差分\(\{3,-1,0,-1,0,0\}\)
一阶差分\(\{3,2,2,1,1\}\)
原数组\(\{3,5,7,8,9\}\)
发现多了好多,这是没有消除影响的结果。
这时一阶为\(\{3,2,2,1,1\}\)
在对\(a_{2,3 + 1} - (2 - 1)\)的同时,也要对\(a_{1,3+1}- sum\), \(sum\) 为询问操作在一阶差分的区间\([1,3]\)的和\(2 + 1 + 1=4\)
这时一阶为\(\{3,2,2,1 - 4,1\}\)
还原,原数组\(\{3,5,7,4,5\}\),即\(\{1+2,2+3,3+4,4,5\}\)。
在本题题解中,也有把这些影响化简的方法,就能只在二阶差分数组操作。
\(\forall x\in[L,R]\subset Z, x + \binom{x - L + k}{k}\)
简单的变换\(\binom{x-L+k}{k} = \binom{x-L+k}{x-L}\)
对于一个组询问\((L,R,k)\),就加\(\binom{k}{0}\),\(\binom{k + 1}{1}\),\(...\),\(\binom{k + R - L}{R - L}\).
在杨辉三角里,这就是一条起点是\((k, 0)\)终点是\((k + R - L, R - L)\)的线段,正好是\(45\)°。
我们知道
移项得到
发现上面
与这条式子很像。
就把它差分一次,得到
这个
这样换一下就漂亮多了:
再差分:
那么差分了\(j\)次,就得到:
当差分了\(k + 1\)次,对于数列中第一个数,\(\binom{0}{0} = 1\neq \binom{-1}{0} = 0\)
这时除了第一个数为 \(1\) 外,剩下的数都为\(0\),再差分也没有意义了。
-
考虑经过\(k + 1\)次差分后,得到 \(1,0,\dots\) 的数列。
-
假如给第\(L\)数也就是这个数列的第一个数\(+1\)。
这里\(\binom{k - k}{0} = 1\)。
到了第二个数,求前面两个数的和,\((1 + \binom{k-(k + 1)}{0}) + \binom{k-(k+1) + 1}{1} = \binom{k - k}{0} + \binom{k-k}{1}=\binom{k - k + 1}{1}\)这就是\(K\)次差分数组的第二个数。
-
以此类推,只要给\(a[k+1][L] +1\),就能推出\(a[k][L...N]\)。
那么在\(R+1\)位置\(-1\),就能不改变\(R+1\)后面的位置了,即算出了 \(a[k][L...R]\)。
-
这样算就发现\(a[k - 1][R...N]\)多了,推出上一阶的差分数组时要考虑有没有算多,考虑 \(K\) 次差分在 \(K - 1\) 次差分的影响,这就是在 \(K - 1\) 次差分的 \(R+1\) 位置,减去这次加入的数列\([L,R]\)在\(K\)次差分下的和。
总的来说,就是对
$$\forall K \in [1,k + 1], a[K][R+1] - sum$$这个数列在\(K\)次差分下为\(\binom{k - K}{0},\binom{k + 1 - K}{1},...,\binom{k + R - L - K}{R - L}\).
即
$$a[K][R + 1] - (\binom{k - K}{0} + \binom{k + 1 - K}{1} + ... + \binom{k + R - L - K}{R - L})$$
通过证明,
$$\binom{k - K}{0} + \binom{k + 1 - K}{1} + ... + \binom{k + R - L - K}{R - L} = \binom{K + R - L - K + 1}{R - L} $$感性理解一下,
在杨辉三角里,就是一条起点是\((k, 0)\)终点是\((k + R - L, R - L)\)的线段,
\[\binom{k}{0}=\binom{k + 1}{0} = 1 \]这个式子相当于把起点\((k,0)\)移到\((k + 1, 0)\),
再通过
\[\binom{k}{i}+\binom{k}{i + 1} = \binom{k + 1}{i + 1} \]这个式子,把这两个点合成\((k + 2,1)\),在与\((k+2,2)\)合成\((k + 3,2)\)......最后就合成到
\[\binom{K+R-L-K+1}{R-L} \] -
所以,对\(\forall K \in [1,k + 1], a[K][R+1] - \binom{K+R-L-K+1}{R-L}\)。
最后就是从\(K+1\)次差分开始,第\(i\)次差分通过前缀和,得到\(i - 1\)的差分,最后得到原数组啦。
CF上用C++14还要把用来差分的数组清零,不然有奇怪的值?
在\(O(\log n)\)的时间内,知道了二阶差分,求出原序列某一位。
求原序列的\(x\)位,
\(c\)为二阶差分,\(b\)为一阶差分,那么\(b_i = \sum_{j=1}^{i}c_j\)。
考虑\(c_j\)会被\(a_x\)计算几次,首先\(c_j\)会对\(b_j\)及以后的\(b\)产生贡献,
其中贡献到\(a_x\)的\(b\)有\(b_j\)到\(b_x\),因此\(a_x\)被贡献\((x - j + 1)\)次
这两个和式都能用树状数组算出。
二维差分。
平面求和,平面修改。
同上题差不多的做法。
差分定义为
和二维前缀和相同。
求a的\((1,1)\)到\((x,y)\)的和。
考虑差分\(d_{i,j}\)的贡献,只有\(a_{k,z}|k\in[i,x],z\in[j,y]\)算入\(d_{i, j}\)。
那么\(d_{i,j}\)被计算\((x-i+1)(y-j+1)\)次.
用四个二维树状数组记录\(d_{i,j},i\times d_{i,j},j\times d_{i,j},i\times j \times d_{i,j}\)
时间复杂度\(O(q\log^2n)\)