差分
-
題單:差分入門
-
概念:
差分:兩個相鄰的數之差。
把原數列進行差分,得到新數列,這是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\)次,
這時所有數都為\(0\),再差分也沒有意義了。
-
考慮經過\(k + 1\)次差分后,得到全0的數列。
-
假如給第\(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)\)
