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