Loading

题解:CF965E Short Code

怎么没有线性做法啊……

建 trie,问题相当于在 trie 上选择深度和尽量小的 \(n\) 个非根节点,使得叶子节点能和其祖先匹配。

一个很自然的想法是贪心地选择深度小的节点,但是会产生多余的节点。

\(s_x\)\(x\) 子树内叶子节点的数量。

若选择了一个节点 \(x\),存在 \(x\) 的某个祖先 \(y\),若 \(y\) 子树内选择的节点超过了 \(s_y\) 个,则 \(x\) 无用。

因为 \(y\) 子树内的叶子节点最多就匹配 \(s_y\) 个节点,这个节点肯定多余。

于是在选择 \(x\) 时,若 \(x\) 的某个祖先 \(y\) 子树内已经选择了 \(s_y\) 个节点,则 \(y\) 的子树以后都不会再选择任何节点了,遍历 \(y\) 的子树,打上不可以选择的标记。

遍历到 \(x\) 发现 \(x\) 有标记,说明 \(x\) 整个子树都被打过标记,可以直接退出。

\(L\)\(n\) 个字符串的长度和。

每个点最多被打一次标记,打标记复杂度 \(O(L)\)

注意直接遍历是 \(O(L|\Sigma|)\) 的,每个点压位 \(26\) 个儿子就是 \(O(L)\) 了。

每个选择的 \(x\) 要枚举所有祖先 \(y\),由于所有 \(x\) 的祖先数量和就是答案,答案 \(\le L\),复杂度 \(O(L)\)

总时间复杂度 \(O(n+L)\),空间复杂度 \(O(L|\Sigma|)\)

Submission

posted @ 2025-02-09 07:18  Mathew_Miao  阅读(9)  评论(0)    收藏  举报