diff --git a/solutions/P17437.md b/solutions/P17437.md new file mode 100644 index 0000000..217e5cd --- /dev/null +++ b/solutions/P17437.md @@ -0,0 +1,114 @@ +# P17437 「LWLV Round 1」Young 题解 + +> 根本没有这样的青题……题解区都看不懂…… + +题意:给定一棵节点带权值的树,断掉两条边,得到三个树,求三个树权值中位数最大是多少。 + +这里我们令 $1$ 为根,边 $id$ 表示连接 $id$ 与其父节点的边,$sum_i$ 表示以 $i$ 为根的子树权值和。 + +## 枚举第一刀 + +先枚举第一条断边 $u$,会将树分为 $u$ 的子树和剩下部分 $A, B$,第二刀只能落在 $A$ 或 $B$ 内部。问题变成:**固定第一刀后,在某一侧内部再切一刀,使三块中位数最大。** + +## 命题:第二刀切出的一定是 $A$ 或 $B$ 的最大或最小子树 + +假设在 $A$ 中切了一刀,分为 $a, A - a$ + +设 $M(a) = median(a, A - a, B)$,考虑 $a \in (0, \frac{A}{2}]$。考虑 $a$ 从 $0 - \frac{A}{2}$ 的过程中。 + +$$ +M(a) = +\begin{cases} +A - a, & B \ge A - a \\ +B, & a \le B \le A - a \\ +a, & B \le a +\end{cases} +$$ + +$M(a)$ 的变化情况如图。 + +![图](https://cdn.luogu.com.cn/upload/image_hosting/8l8gqxsl.webp) + +其中三种不同颜色的框分别代表三个区间。因此 $median$ 的最大值只可能在 $a \rightarrow 0$ 或 $a \rightarrow \frac{A}{2}$ 时取到。对于第二刀切在 $B$ 中时也是类似的。其中,$a \rightarrow 0$ 表示要切出最小子树,而 $a \rightarrow \frac{A}{2}$ 表示 $a, A - a$ 尽可能均衡,此时 $B$ 要尽可能小才能使得中位数最大。 + +## 预处理子树最大、最小可切值 + +若第二刀在 $A$ 内部,则需要用到子树的最大、最小可切值。 + +记录 $dmax_i, dmin_i$ 表示以 $i$ 为根的子树的能切出的最大/最小权值子树,则结果为以一个儿子节点为根的子树的权值和或者以一个儿子节点为根的子树能切出的最大/最小权值子树。 + +$$ +\begin{aligned} +dmax_i =& \max(\max(s_u, dmax_u), u \in child_i) \\ +dmin_i =& \min(\min(s_u, dmin_u), u \in child_i) +\end{aligned} +$$ + +## 预处理“补集方向”最小、最大可切值 + +若第二刀切在 $A$ 的补集 $B$ 的方向,则需要“补集方向”的最小、最大可切值。 + +令 $umax_i, umin_i$ 为补集方向的最大最小可切值。这个要从上往下递推。 + +根节点补集为空:$umin_1=\inf, umax_1=-\inf$。 + +对于节点 $i$ 的儿子 $v$,$v$ 的补集由三部分组成。 + +1. $i$ 的补集。 +2. $i$ 与父节点之间的边切出来的那一大块(权值 $s_1 - s_u, u\ne 1$)。 +3. $i$ 的其他儿子的子树方向。 + +$$ +\begin{aligned} +umin_v =& \min(umin_u, (s_1 - s_u), \min_{x\in child_u, x\ne v}\min(S_x, dmin_x))\\ +umax_v =& \max (umax_u, (s_1 - s_u), \max_{x\in child_u, x\ne v}\max(S_x, dmax_x)) +\end{aligned} +$$ + +### 线性求“其他儿子”的极值(换根dp) + +如果对每个儿子 $v$ 都重新扫一遍所有兄弟,复杂度会退化成 $O(n^2)$。 + +对每个节点 $u$,预处理它所有儿子分支的候选值: + +$$ +c_x = \min(s_x, dmin_x), C_x = \max(s_x, dmax_x). +$$ + +记录这些候选的: + +- 最小值 $min1$ 与次小值 $min2$,以及最小值来源儿子 $minId$。 +- 最大值 $max1$ 与次大值 $max2$,以及最大值来源儿子 $maxId$。 + +计算儿子 $v$ 时: + +- 若 $v\ne minId$,兄弟方向最小候选就是 $min1$,否则用 $min2$。 +- 若 $v\ne maxId$,兄弟方向最大候选就是 $max1$,否则用 $max2$。 + +再与 $umin_u, umax_u$ 以及 $s_1 - s_u$ 合并,就得到 $umin_v, umax_v$。 + +这样每个节点只扫一遍儿子,整体 $O(n)$。 + +--- + +## 最终求答案 + +先预处理上述的 $umax, umin, dmax, dmin$。 + +枚举第一刀的位置 $v$,切成 $A, B$ 两块,分两种情况:第二刀在 $A$ 中或第二刀在 $B$ 中。 + +### 第二刀在 $A$ 内部 + +第二刀切出的 $a \in \{dmax_v, dmin_v\}$。 + +三块分别为 $a, A - a, B$,答案为 $median(t, A-t, B)$。 + +### 第二刀切在 $B$ 内部。 + +第二刀切出的 $b \in \{umin_v, umax_v\}$ + +三块分别为 $A, b, B - b$,答案为 $median(A, b, B - b)$ + +记录最大答案即可。 + +[code](../P17437.cpp)