dfs序和树状数组
点——子树类问题还算简单,这里就不展开讨论。下面主要针对Loj的板子题,谈谈我对dfs序的的见解。需要一些dfs序和差分的思想。
规定:
- 字母xxx即可表示节点,亦可表示以该节点为根的子树。
- (x,y)(x,y)(x,y)表示xxx到yyy的路径。
- sum[in[x],out[y]]sum[in[x], out[y]]sum[in[x],out[y]]表示按照dfs序对差分序列求和。
146
给一棵有根树,这棵树由编号为1…n 的n 个结点组成。根结点的编号为 r。每个结点都有一个权值,结点i 的权值为w[i] 。
接下来有 m组操作,操作分为三类:
1 a b x
,表示将「结点a 到结点 b的简单路径」上所有结点的权值都增加x ;2 a
,表示求结点 a的权值。3 a
,表示求 a的子树上所有结点的权值之和。
这个题还是用dfsdfsdfs序,但是差分规则变了
先假设每一个点的权值都是0,那么对单点的数据更新将泛化到对单点构成的路径进行更新。因为全部赋值为0,那么无论做什么差分,其差分序列都是0。
引理一:
任何 单点修改可解释为路径修改。
引理二:
累计权值更改可以看作单次权值更改。
不证自明。
接着开始下定义:
定义一:
任何点的点权为sum[in[i],out[i]]sum[in[i], out[i]]sum[in[i],out[i]]。
这个定义决定了这个差分序列是树状有序的,而非一维有序。
推理一:
对该序列路径差分不会修改单点查询点权。
证明:
从全0序列开始,不妨设对路径(x,y)(x,y)(x,y)进行路径差分。假设差分值为w,这时会有如下操作。
lca=lca(u,v),fa=fa[lca].in[lca]−=win[fa]−=win[x]+=win[y]+=w lca = lca(u, v), fa = fa[lca].\\ in[lca]-=w \\ in[fa]-=w\\ in[x]+=w\\ in[y]+=w\\ lca=lca(u,v),fa=fa[lca].in[lca]−=win[fa]−=win[x]+=win[y]+=w
由dfsdfsdfs序的性质可得,in[fa]<in[x],in[fa]<in[y]in[fa] < in[x], in[fa] < in[y]in[fa]<in[x],in[fa]<in[y],且in[lca]≤in[x],in[lca]≤in[y]in[lca] \leq in[x], in[lca]\leq in[y]in[lca]≤in[x],in[lca]≤in[y]。
不妨设in[x]<in[y]in[x] < in[y]in[x]<in[y]
- 假设在in[lca]in[lca]in[lca]和in[x]in[x]in[x]之间夹了一子树iii,其和x相互独立,那么计算子树iii内任意一个节点的权值时,上述修改不会对其产生任何影响。
- 在第一条的假设下,令子树iii 包含xxx,由dfsdfsdfs序的性质可得,out[i]≥in[x]out[i] \geq in[x]out[i]≥in[x],所以out[i]≥out[x]≥in[x]out[i]\geq out[x]\geq in[x]out[i]≥out[x]≥in[x]。因此上述修改一定影响到了iii的权值,使iii的权值增加w。
- 假设子树iii包含于xxx,那么out[i]≥in[i]≥in[x]out[i]\geq in[i]\geq in[x]out[i]≥in[i]≥in[x]。即完全不受影响。
- 假设子树iii包含lcalcalca。那么