UOJ Logo heqingyu的博客

博客

树链剖分的基本思想

2017-12-31 22:36:32 By heqingyu

一、树链剖分的作用

  通常是求树上u到v的路径节点之和

  这个问题很容易可以想到设f[i]表示根节点到i节点的节点之和

  t=lca(u,v),然后可以把u->v划分为u->t+t->v-t;

  则有结论:u->v=f[u]+f[v]-2*f[t]+t,这样就可以求出来了

  但是加上u到v的路径上的节点值的修改的话,就必须用树链剖分了。。。

二、几个概念:

  1.重儿子:一个节点的所有儿子中子树最大的那一个(相同任意取一个)

  2.轻儿子:除了重儿子以外的所有其他儿子

  3.重边:father连向重儿子的边

  4.轻边:除了重边以外的边

  5.重链:一条路径,上面全部都是由重儿子构成(即全为重边)

三、几个推论:

  1.两条重链之间必然有一些轻边连接

  2.我们用一条重链的起始节点来表示一条重链(每个节点只会属于一条重链)

  3.bel[x]表示x节点的重链的开头节点

四、问题的解决:

  首先对于修改操作,将lca(u,v)求出,然后判断bel[x]是否等于bel[y]

  1.如果等于,那就可以直接对一条重链上的节点进行修改

  2.对于每条重链来维护一段区间信息,然后如果不同的话,就可以不断地跳,直到跳到同一条重链上

  3.考虑每个节点都肯定包含在一条重链中,因此为每条重链建一棵线段树,然后就可以实现区间查询和区间修改

评论

xuruiyang
@heqingyu 大佬!!!
  • 2018-01-01 13:38:47
mjy0724
"2.如果不等于,那就把x和y同时跳到他们的重链的顶端,然后跨越轻边,继续刚才的过程" 你再想想,这不是倍增求LCA啊QAQQQ
  • 2018-01-02 15:15:14
oi_loser
单点修改、链求和也可以LCA+DFS序+树状数组,1个log。
  • 2018-01-07 20:54:16