差分、二维差分、树上差分

一维差分:

给你一个数组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.

至于为什么会有差异,用手画一画就理解了。

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