洛谷 P8176 题解
upd:之前加粗的 markdown 挂了。
尘沙里稀疏的草和木凋零朽枯
他在我的耳边计算着明天的路途
至今为止我做过最困难的一道思维题。定数
第 1 部分:结论 1\sim3 。
称一个点染
我们主要分析一个合法染色方案需要满足的性质。我们将推导出
结论
先 DFS 两遍求出树的一条直径
-
若
\text{dis}(p,q)<k-1 ,则不存在任何可能的旅行。此时答案=2^n 。先把这种情况判掉。 -
若
\text{dis}(p,q)\geq k-1 ,则树的直径恰有k 种染法。对于每个i ,从p 到q 数第i,i+k,i+2k,\cdots\cdots 个点的\text{col} 必须都相同。记只将第i 个等价类染1 的染法为第i 种染法。
我们将
结论
结论
结论
第 2 部分:结论 4\sim8 。
但还有一种旅行
结论
结论
- 若
\text{dis}(u,p)\geq k-1 ,则\text{class}(u)=\text{dis}(u,p)\bmod k 。 - 若
\text{dis}(u,q)\geq k-1 ,则\text{class}(u)=\big(\text{dis}(p,q)-\text{dis}(u,q)\big)\bmod k 。
结论
- 两侧点
u 的父亲\text{Fa}(u) 一定也是两侧点。因为\text{dis}(u,p),\text{dis}(u,q) 都只会减小1 ,但是h_u 至少会增加1 。 - 因此,所有的一侧点构成若干棵子树。将这些子树的根拿出来,称这些点为关键点。
结论
- 因为
v 满足这3 个条件,一定存在两个直径上的点p',q' 分别在\text{project}(u) 的左侧和右侧,使得\text{dis}(v,p')=\text{dis}(v,q')=k-1 。 - 假如
u 染1 的话,直径上p'\sim q' 必须全都染0 ,这是连续2k-2\text{dep}(v)-1\geq2k-(k-1)-1=k 个全都染0 的点,矛盾!
结论
结论
-
若
\text{dep}(u)>\left\lfloor\dfrac{k-1}2\right\rfloor ,则\text{dis}(u,p)\geq2\Big(\left\lfloor\dfrac{k-1}2\right\rfloor+1\Big)\geq k ,\text{dis}(u,q) 同理。因此u 是有归属的。 -
若
\text{dep}(u)\leq\left\lfloor\dfrac{k-1}2\right\rfloor ,不妨设\text{dis}(u,p)\geq\text{dis}(u,q) 。因为u 是两侧点,这意味着u 的子树内存在v 使得\text{dis}(v,q)\geq k-1 。考虑最浅的那个v ,有\text{dep}(v)=k-\text{dis}(\text{project}(u),q)-1 。由于\text{dep}(v)\leq\text{dis}(\text{project}(u),q) ,因此\text{dep}(v)\leq\left\lfloor\dfrac{k-1}2\right\rfloor 。
要么
第 3 部分:结论 9\sim10 。
现在考虑一侧点构成的子树的根(即关键点)
结论
- 若
\text{dis}(u,v)\bmod k=0 ,则u 必须染1 。否则u 必须染0 。
因此若
反之若
再去掉不一定成立的假设,考虑存在不经过直径的旅行
结论
- 在同一个
\text{project}(u) 下\text{dis}(u,p)=\text{dep}(u)+\text{dis}\big(\text{project}(u),p\big) ,因此\text{class}(u) 是仅关于\text{dep}(u) 的斜率=\pm1 的一次函数。我们只需要 DFS 每个两侧点u ,并得到u 的所有子树的高度的最大值和次大值即可。
最后,我们来简略的叙述我们的做法。具体实现可以看下方的代码链接,代码和题解叙述的逻辑是完全一致的。
我们维护两个长度为
-
对于每个关键点
u ,u 的子树对\text{ans}(i) 的贡献是一个区间乘的形式。考虑什么时候
p\sim\text{Fa}(u) 会全都染0 。p\sim\text{Fa}(u) 都要么在直径上要么为两侧点,因此它们都要么是有归属的,要么必须染0 。取出
p\sim\text{Fa}(u) 上所有有归属的点的\text{class} 值构成的集合S 。假设我们采用第i 种染法,那么如果i\not\in S ,p\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\} ,因此可以直接打后缀乘标记,不需要求乘法逆元。 -
对于每个两侧点
u ,考虑u 向p 方向延伸出的长度为k-1 的链。取出它的集合S ,则在S 中出现0 次或2 次的i 将会被\text{ban} 掉。这将会\text{ban} 掉\mathcal{O}(1) 个区间,直接差分即可。u 向q 方向延伸出的链同理。 -
对于每个两侧点
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) 个区间。
最终把还活着的