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