洛谷 P8176 题解

· · 题解

upd:之前加粗的 markdown 挂了。

尘沙里稀疏的草和木凋零朽枯
他在我的耳边计算着明天的路途

至今为止我做过最困难的一道思维题。定数 \bold{\texttt{Lv}\ 18} 应该没有问题。

1 部分:结论 1\sim3

称一个点染 1 指这个点上有水井,染 0 指这个点上无水井。称一条长度为 k-1 的路径为一个旅行。

我们主要分析一个合法染色方案需要满足的性质。我们将推导出 10 条结论,随着结论的推导揭示我们的做法。

结论 1. 若两个点 u,v 满足 \text{dis}(u,v)=k,则 \text{col}(u)=\text{col}(v)

先 DFS 两遍求出树的一条直径 p\sim q

我们将 p\sim q 上的每个点拿出来,以它们为根向远离直径的方向 DFS 这棵树。我们预处理出一些信息。记 \text{project}(u)up\sim q 上的投影,记 \text{dep}(u) 表示以 \text{project}(u) 为根 u 的深度,再记 h_uu 子树的高度,即 u 子树内最深的点 v\text{dep}(v)-\text{dep}(u)

结论 2. 对于任意一个点 u\max\limits_{i=1}^n\text{dis}(u,i)=\max\big\{\text{dis}(u,p),\text{dis}(u,q)\big\}

结论 3. 不需要考虑那些经过直径但两个端点都不在直径上的旅行 u\sim v。若其他所有旅行都满足要求,则这些旅行一定满足要求。

结论 3 是此题的关键结论。设 uv 的左侧。因为 p\sim q 是直径,一定存在两个直径上的点 u',v' 分别在 \text{project}(u)\text{project}(v) 的左侧和右侧,使得 \text{dis}\big(u',\text{project}(u)\big)=\text{dep}(u)\text{dis}\big(v',\text{project}(v)\big)=\text{dep}(v)。那么 u'\sim v'u'\sim v 以及 u\sim v' 都是旅行。如果它们都满足要求,则 \text{sum}(u,v)=\text{sum}(u',v)+\text{sum}(u,v')-\text{sum}(u',v')=1+1-1=1,因此 u\sim v 也满足要求。

2 部分:结论 4\sim8

但还有一种旅行 u\sim v 是不经过直径的,与直径没有交点。先假设不存在这样的旅行。注:以下 u,v 都默认不在直径上。

结论 4. 若叶子 u 满足 h_u+\text{dis}(u,p)<k-1h_u+\text{dis}(u,q)<k-1,则任何可能的旅程都不包含 u。将 u 删去并将答案 \times2

结论 5. 若结点 u 满足 \text{dis}(u,p)\geq k-1\text{dis}(u,q)\geq k-1,则 u 处在某个等价类中。称这样的结点 u 是有归属的,否则是无归属的。

结论 6. 若结点 u 满足 h_u+\text{dis}(u,p)\geq k-1h_u+\text{dis}(u,q)\geq k-1,则称 u 是两侧点,否则称 u 是一侧点。

结论 7. 若结点 u 的子树内存在 v 使得 \text{dis}(v,p)\geq k-1\text{dis}(v,q)\geq k-1\text{dep}(v)\leq\left\lfloor\dfrac{k-1}2\right\rfloor,则 u 必须染 0

结论 8. 若结点 u 是两侧点,则要么 u 是有归属的,要么 u 必须染 0

结论 8 是此题的关键结论。在某种意义上,结论 4\sim 7 都是为结论 8 服务的。

要么 u 是有归属的,要么 u 必须染 0。因为二者的判别是根据 \text{dep}(u) 是否 >\left\lfloor\dfrac{k-1}2\right\rfloor,所以这个结论很有用。

3 部分:结论 9\sim10

现在考虑一侧点构成的子树的根(即关键点)u\text{Fa}(u) 要么在直径上要么为两侧点。不妨设 \text{dis}(u,p)\geq\text{dis}(u,q)

结论 9. 若结点 u 被一条长度 \geq k-1 的路径 p'\sim q' 包含,且 p'\sim q' 上存在一个点 v 已经确定染 1,则 u0 还是 1 也已经确定。

因此若 p\sim\text{Fa}(u) 中存在 1,则 u 子树内的染色方案已经唯一确定。

反之若 p\sim\text{Fa}(u) 全都染 0,则需要给 u 的子树染一个极小割。即 u 的子树内染 1 的结点 v 一定满足 \text{dis}(v,p)\leq k-1,并且子树内所有的叶子 v 都满足 vu 的路径上恰有一个染 1 的结点。我们记这个为 F_uF_u 可以通过 DP 直接求出。

再去掉不一定成立的假设,考虑存在不经过直径的旅行 u\sim v 时的情况。

结论 10. 若旅行 u\sim v 与直径无交,那么 u\sim v 上的所有点都是两侧点。

最后,我们来简略的叙述我们的做法。具体实现可以看下方的代码链接,代码和题解叙述的逻辑是完全一致的。

我们维护两个长度为 k 的序列 \text{ok}(i)\text{ans}(i) 分别表示第 i 种染法是否可行以及其合法方案数,初始值为全 1

  1. 对于每个关键点 uu 的子树对 \text{ans}(i) 的贡献是一个区间乘的形式。

    考虑什么时候 p\sim\text{Fa}(u) 会全都染 0p\sim\text{Fa}(u) 都要么在直径上要么为两侧点,因此它们都要么是有归属的,要么必须染 0

    取出 p\sim\text{Fa}(u) 上所有有归属的点的 \text{class} 值构成的集合 S。假设我们采用第 i 种染法,那么如果 i\not\in Sp\sim\text{Fa}(u) 就会全都染 0

    于是我们要对所有的 i\not\in S\text{ans}(i) 乘上 F_u。我们将 p\sim\text{Fa}(u) 拆成 p\sim\text{project}(u)\big(\text{project}(u),\text{Fa}(u)\big] 两个部分。那么每个部分内的 S 分别构成一段区间。

    进一步的观察表明需要区间乘的 \mathcal{O}(1) 个区间的右端点 r\in\Big\{k-1,\left\lfloor\dfrac{k-1}2\right\rfloor\Big\},因此可以直接打后缀乘标记,不需要求乘法逆元。

  2. 对于每个两侧点 u,考虑 up 方向延伸出的长度为 k-1 的链。取出它的集合 S,则在 S 中出现 0 次或 2 次的 i 将会被 \text{ban} 掉。这将会 \text{ban}\mathcal{O}(1) 个区间,直接差分即可。uq 方向延伸出的链同理。

  3. 对于每个两侧点 u,求出 u 的所有子树的高度的最大值 f 和次大值 s。若 f+s\geq k-1,则需要考虑以 u\text{LCA} 的与直径无交的旅行。其中限制最严的一个较短子树的高度是 \min\Big\{s,\left\lfloor\dfrac{k-1}2\right\rfloor\Big\},取出它的集合 S,相应 \text{ban}\mathcal{O}(1) 个区间。

最终把还活着的 \text{ans}(i) 加起来即可。时间复杂度 \mathcal{O}(n),空间复杂度 \mathcal{O}(n)。代码链接:https://loj.ac/s/1799853。