DFS 序 1
题目要求:
① u u u节点权值 + x +x +x
② 询问 u u u子树权值和
- u u u节点权值 + x +x +x :直接加
- u u u子树权值和:dfs序+树状数组
DFS 序 2
题目要求:
① u u u节点子树权值 + x +x +x
② 询问 u u u子树权值和
- u u u节点子树权值 + x +x +x:dfs序+区间修改
- 询问 u u u子树权值和:dfs序+区间求和
区修+区改可以用2个树状数组或者lazy线段树
LOJ提交代码 DFS 序 2
DFS 序 3,树上差分 1
题目要求:
① u ⇝ v u\leadsto v u⇝v 路径 + x +x +x
② 询问 u u u节点权值
③ 询问 u u u子树权值和
采用自底向上的差分 O ( n log n ) O(n\log n) O(nlogn):
- u ⇝ v u\leadsto v u⇝v路径 + x +x +x: u u u和 v v v分别 + x +x +x而LCA以及LCA的父亲节点分别 − x -x −x
- u u u节点权值:由于采用自底向上差分,不难得出原 u u u节点的权值 → \to → u u u节点子树权值和,采用dfs序+树状数组即可解决
- u u u子树权值和:考虑 u u u子树一个节点 v v v,经过操作二求法得知对于差分后节点 v v v的值再求 u ⇝ v u\leadsto v u⇝v的路径上的实际点权值时(子树),都会将 v v v的贡献加上即差分树中 v v v的值对子树 u u u权值和的贡献即 v a l v × ( d e p v − d e p u + 1 ) = v a l v × d e p v + ( d e p u − 1 ) × v a l v val_v×(dep_v-dep_u+1)=val_v×dep_v+(dep_u-1)×val_v valv×(depv−depu+1)=valv×depv+(depu−1)×valv于是有 u u u子树权值和为 ∑ v ∈ T r e e u v a l v × d e p v − ( d e p u − 1 ) × ∑ v ∈ T r e e u v a l v \sum_{v\in Tree_u}val_v×dep_v-(dep_u-1)×\sum_{v\in Tree_u}val_v v∈Treeu∑valv×depv−(depu−1)×v∈Treeu∑valv由此得知只需要在用一个树状数组维护 v a l v × d e p v val_v×dep_v valv×depv即可根据dfs序求出子树 v a l v × d e p v val_v×dep_v valv×depv和,不难得出 u u u子树权值和问题也迎刃而解
DFS 序 4
题目要求:
① u u u节点权值 + x +x +x
② u u u节点子树权值 + x +x +x
③ 询问 u ⇝ v u\leadsto v u⇝v路径节点权值和
对于
u
⇝
v
u\leadsto v
u⇝v路径权值和可以拆分成4条路径:
r
o
o
t
⇝
u
root\leadsto u
root⇝u,
r
o
o
t
⇝
v
root \leadsto v
root⇝v,
r
o
o
t
⇝
root \leadsto
root⇝LCA,
r
o
o
t
⇝
root \leadsto
root⇝LCA的父亲,于是只需要维护根节点到某个节点的权值和即可解决询问
于是我们让每个节点的权值为到根节点的权值和
- u u u节点权值 + x +x +x:此操作会导致 u u u子树中所有节点到根节点的权值和 + x +x +x,因此需要让 u u u节点子树权值都 + x +x +x
- u u u节点子树权值 + x +x +x:考虑 u u u子树中一个节点 v v v,不难得知 u ⇝ v u\leadsto v u⇝v路径上所有点都会让 v v v节点权值 + x +x +x即 v v v节点需要增加 x × ( d e p v − d e p u + 1 ) = x × d e p v − x × ( d e p u − 1 ) x×(dep_v-dep_u+1)=x×dep_v-x×(dep_u-1) x×(depv−depu+1)=x×depv−x×(depu−1)不难发现 − x × ( d e p u − 1 ) -x×(dep_u-1) −x×(depu−1)可以直接子树修改即可而 x × d e p v x×dep_v x×depv说明每一个 x x x对当前节点权值增加 x × d e p v x×dep_v x×depv,只需要用一个树状数组记录一下每个点最终有多少 x x x即可。