dfs序和树状数组

dfs序和树状数组

点——子树类问题还算简单,这里就不展开讨论。下面主要针对Loj的板子题,谈谈我对dfs序的的见解。需要一些dfs序和差分的思想。
规定:

  1. 字母 x x x即可表示节点,亦可表示以该节点为根的子树。
  2. ( x , y ) (x,y) x,y表示 x x x y y y的路径。
  3. s u m [ i n [ x ] , o u t [ 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的子树上所有结点的权值之和。

这个题还是用 d f s dfs dfs序,但是差分规则变了

先假设每一个点的权值都是0,那么对单点的数据更新将泛化到对单点构成的路径进行更新。因为全部赋值为0,那么无论做什么差分,其差分序列都是0。

引理一:

任何 单点修改可解释为路径修改。

引理二:

累计权值更改可以看作单次权值更改。

不证自明。

接着开始下定义:

定义一:

任何点的点权为 s u m [ i n [ i ] , o u t [ i ] ] sum[in[i], out[i]] sum[in[i],out[i]]

这个定义决定了这个差分序列是树状有序的,而非一维有序。

推理一:

对该序列路径差分不会修改单点查询点权。

证明:

从全0序列开始,不妨设对路径 ( x , y ) (x,y) (xy)进行路径差分。假设差分值为w,这时会有如下操作。
l c a = l c a ( u , v ) , f a = f a [ l c a ] . i n [ l c a ] − = w i n [ f a ] − = w i n [ x ] + = w i n [ 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
d f s dfs dfs序的性质可得, i n [ f a ] < i n [ x ] , i n [ f a ] < i n [ y ] in[fa] < in[x], in[fa] < in[y] in[fa]<in[x],in[fa]<in[y],且 i n [ l c a ] ≤ i n [ x ] , i n [ l c a ] ≤ i n [ y ] in[lca] \leq in[x], in[lca]\leq in[y] in[lca]in[x],in[lca]in[y]

不妨设 i n [ x ] < i n [ y ] in[x] < in[y] in[x]<in[y]

  • 假设在 i n [ l c a ] in[lca] in[lca] i n [ x ] in[x] in[x]之间夹了一子树 i i i,其和x相互独立,那么计算子树 i i i内任意一个节点的权值时,上述修改不会对其产生任何影响。
  • 在第一条的假设下,令子树 i i i 包含 x x x,由 d f s dfs dfs序的性质可得, o u t [ i ] ≥ i n [ x ] out[i] \geq in[x] out[i]in[x],所以 o u t [ i ] ≥ o u t [ x ] ≥ i n [ x ] out[i]\geq out[x]\geq in[x] out[i]out[x]in[x]。因此上述修改一定影响到了 i i i的权值,使 i i i的权值增加w。
  • 假设子树 i i i包含于 x x x,那么 o u t [ i ] ≥ i n [ i ] ≥ i n [ x ] out[i]\geq in[i]\geq in[x] out[i]in[i]in[x]。即完全不受影响。
  • 假设子树 i i i包含 l c a lca lca。那么 o u t [ i ] ≥ o u t [ y ] ≥ o u t [ x ] ≥ i n [ l c a ] ≥ i n [ f a ] ≥ i n [ i ] out[i]\geq out[y]\geq out[
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值