zoukankan      html  css  js  c++  java
  • 树链剖分的一种用法

    这篇文章好像发得有点迟了啊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值比较复杂,还可以考虑使用线段树维护每个点的子树。

  • 相关阅读:
    如何成为合格的技术面试官?
    互联网上有多少个网站?
    前端领域不需要架构师?
    WebAssembly 简介
    git常用命令
    剑指offer-基本思想学习(未包括代码)
    OS知识点总结
    对软件工程的一点认识
    项目实现过程的每个阶段
    编译原理课程设计总结
  • 原文地址:https://www.cnblogs.com/zzqsblog/p/6873879.html
Copyright © 2011-2022 走看看