首页 > 代码库 > 树链剖分的一种用法
树链剖分的一种用法
这篇文章好像发得有点迟了啊QAQ之前忘了发了
又好久没更了,讲一个提高组内容。
我们来考虑一个有趣的问题,我们有一棵有根树,每个点有点权,要求支持单点加,子树加。
询问比较奇怪,每个点有一个点权x,假装不变,每次询问指定一个点p,对于它的每个孩子(直系的)s,将x[s]*s的子树和相加输出。
先假装没有子树加,考虑直接用树链剖分来做这个东西。那么我们询问某个点的孩子的时候,我们发现有两种孩子,一种是重孩子,一种是轻孩子。
对于重孩子,因为只有一个,所以我们可以直接在dfs序上搞一个树状数组统计。
如果是轻孩子?考虑一个被计入答案的点,那么这个轻孩子肯定是这个点的祖先,而且是某条重链的顶端。我们可以在单点加的时候暴力跳它往上的重链,跳到某重链顶端时更新顶端的父亲的答案,然后继续跳。考虑到重链剖分的复杂度,这样做是一个log的。
接下来我们考虑子树加怎么做。假设我们询问a的子树,子树b之前进行了一次子树加。如果a和b子树不交显然对答案没有影响。如果a是b的祖先(不包括b),那么我们可以把b整棵子树当成一个点,像上面那样跳重链更新答案。如果b是a的祖先(包括a),那么a子树的每个点都受到了影响,我们只要把a的轻儿子的x相加乘上计入贡献即可,这个可以用两遍dfs序来实现。
用类似的方法可以支持点权修改和询问子树dp值。如果dp值比较复杂,还可以考虑使用线段树维护每个点的子树。
树链剖分的一种用法
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。