一维差分:
给你一个数组a[1] ~ a[n],有Q个操作,每一操作给定 l , r , x 表示 [l, r] 区间所有的数都加上 x, 让你求最后a[1] ~ a[n] 最后各自是多少,要求用 O(n) 复杂度 完成。
设定一个差分数组C[] , 对于每一次操作 c[l] += x , c[r + 1] -= x. 最后对C 做一遍前缀和。C[i] 最后就得到 a[i] 这个数变化了多少。
a[1] ~ a[n] 最后各自就是 a[i] + C[i].
二维差分:
和一维差分差不多, 每一次给定 左上角 (x1,y1),右下角 (x2,y1),x
每次操作 C[x1][y1] += x , C[x2 + 1][y2 + 1] += x , C[x1][y2 + 1] -= x , C[x2 + 1][y1] -= x;
然后做一遍二维前缀和。
树上差分:
思想和一维二维差分一样,只不过最后做和的时候不同。树上差分的做和 C[i] = C[i] + (其子树的所有节点的C).也就用dfs再跑一次树 求和。
还有一点值得注意的就是,点权差分和边权差分有些许不同。
例如都是改变 u, v 这一条链上的。
点权:每一次 C[u] += val, C[v] += val , C[lca(u,v)] -= val , C[Fa_LCA(u,v)] -= val.
边权:C[u] += val , C[v] += val , C[lca(u,v)] -= 2 * val.
至于为什么会有差异,用手画一画就理解了。