CF Gym 102759I
题意
给出一颗 $n$ 个节点的树以及 $Q$ 个操作,操作可能的类型如下;
1 u
,把 $u$ 子树里的所有 $A_i$ 加一。2 u v
,把 $u$ 到 $v$ 路径上的所有 $A_i$ 加一。
每次操作后查询如下式子:$$ \min_{1 \leq y \leq n}\sum_{1 \leq x \leq n}a_xdis(x,y) $$
做法
考虑维护树的带权重心。
我们记 $S$ 为 $\sum A_i$,$sz_u$ 为 $u$ 子树里的 $\sum A_i$ 以及 $b_{dfn_i}=a_i$。有如下性质:
一个树必定存在至少一个带权重心,且带权重心必定的权值种类数唯一。
$b$ 数组的一段前缀必定对应了树上的一个连通块。
从左往右找到第一个 $i$ 使得 $\sum b_{1...i} \geq \frac{S}{2}$,那么 $i$ 必定存在一个祖先 $y$ 满足 $y$ 是 $i$ 的带权重心。
前两点比较显然。
最后一条利用构造法证明:若 $i$ 不是树的带权重心,必然可以移动到 $father_i$ 使得新的 $i$ 的所有子树大小 $\leq \frac{S}{2}$。重复上述操作,最终将会得到一个满足条件的 $y$。
这时问题就转化为了固定 $y$,查询:$$ \sum_{1 \leq x \leq n}a_xdis(x,y) $$ 假设这个问题是静态的,可以利用换根 $\text{DP}$ 轻松解决。可是树是实时变化的,故而考虑用树链剖分维护。
具体的,要算贡献需要分两类边讨论:
-
$y\to root$ 路径上的边(深度较浅的那个记为 $x$)。
贡献为 $sz_x-sz_y$。
-
其余的边(深度较深的那个记为 $x$)
贡献为 $sz_x$。
初始时预处理点 $u$ 到根路径上的点数。进行链修改来维护 $sz$ 数组,查询时直接 $\sum sz_y$ 减去 $u$ 到根路径上点数 $\times sz_y$。