题解:[JAG 2023 Summer Camp #3] LCP Queries
根号分治。
记 \(S=\sum|s_i|,T=\sum|t_i|,K=\sum k_i,\)
对于 \(|s_i|>B\),这样的 \(s_i\) 只有 \(\mathcal O(\frac{S}{B})\) 个。而对于任意 \(s_i\),依次考虑匹配 \(t_{a_1},t_{a_2},\dots\),知道一个 \(t\) 不能完整的匹配。这个过程中需要查询任意 \(s\) 的一个后缀和任意 \(t\) 的 LCP,将所有 \(s\) 和 \(t\) 拼在一起跑 SA 即可 \(\mathcal O(1)\) 查询。这样每个 \(s_i\) 可以在 \(\mathcal O(k)\) 的复杂度求出 \(\operatorname{LCP}(u,s_i)\),这部分复杂度 \(\mathcal O((S+T)\log(S+T)+\frac{SK}{B})\)。
对于 \(|s_i|\le B\),只有 \(u\) 的前 \(B\) 个字符有用。设以 \(u[1:i]\) 为前缀的 \(s_i\) 的个数为 \(cnt_i\),则 \(\sum\operatorname{LCP}(u,s_i)=\sum cnt_i\)。将所有这样的 \(s_i\) 插到一棵 trie 树中,即可求出所有 \(cnt_i(1\le i\le B)\)。这部分复杂度为 \(\mathcal O(S+QB)\)。
两部分结合,取合适的 \(B\) 可得到复杂度 \(\mathcal O((S+T)\log(S+T)+\sqrt{SKQ})\)。
看提交记录似乎有一个更快的做法,不确定是复杂度更优还是常数更优。

浙公网安备 33010602011771号