题解:qoj#8306 Boring Problem
有趣的题目。
题意简述
给出 \(n\) 个长度为 \(m\) 的字符串 \(t_1,t_2,\dots,t_n\),都由前 \(c\) 个小写字母组成。
定义 \(E(S)\) 为当前有字符串 \(S\),每过 \(1\) 秒,会在 \(S\) 后面随机接一个字母,其为第 \(i(1\leq i\leq c)\) 个小写字母的概率是 \(p_i\),期望多少秒后 \(t_1,t_2\dots,t_n\) 中的至少一个会作为子串出现。
现在给定字符串 \(T\),求出对于 \(T\) 的每个前缀 \(T[1:i]\),求出 \(E(T[1:i])\)。
\(n\leq 100,nm\leq10^4,c\leq 26,|T|\leq 10^4\)。
解法
\(n=1\) 时是 P4548 [CTSC2006] 歌唱王国。不过这个题数据范围较小,不太可能是简单结论。
对于 \(n>1\) 的情况,不妨设 \(t_i\) 互不相同。
多串匹配,考虑建出 AC 自动机。设若当前在 \(x\),加上字符 \(i\) 转移到结点 \(tran(x,i)\),期望需要 \(E(x)\) 秒匹配上,那么有:
AC 自动机总结点数是 \(O(nm)\) 的,直接高斯消元求出所有 \(E\) 是 \(O(n^3m^3)\) 的。
上面的方程有 \(O(nm)\) 个变量,考虑利用这些约束的特殊性进行手动消元/代换,以减小变量数量再高斯消元。
AC 自动机是基于 trie 树的,记结点 \(x\) 在树上的深度为 \(dep(x)\),我们现在按深度一层一层地处理 \(E(x)\)。先将根结点设为变量。假设当前我们已经处理完所有 \(dep(x)\leq D\) 的 \(x\),那么考察每个 \(dep(x)=D\) 的 \(x\),对于每个 \(i=1,2,\dots,c\):
- 若 \(dep(tran(x,i))\leq D\),那么 \(E(tran(x,i))\) 已经处理过了。
- 若 \(dep(tran(x,i))> D\),那么根据 AC 自动机的性质可以发现,\(tran(x,i)\) 一定是 \(x\) 在 trie 树上的子结点。设这样的点有 \(ch_x\) 个,那么由 \(E(x)=\sum_{i=1}^cp_iE(tran(x,i))+1\),可以将其中的 \(ch_x-1\) 个子结点的 \(E\) 设为变量,就可以算出剩下的那个子结点的 \(E\)。
在上面的过程中,总变量数量为 \(1+\sum_x\max\{0,ch_x-1\}=\sum_x[ch_x=0]\), 也就是叶子数量 \(n\)。而对于每个叶子 \(x\),\(E(x)=0\) 的约束在上面也没有用到。所以我们得到了 \(n\) 个变量和 \(n\) 个约束,可以证明足以求解出所有变量,进而求出所有 \(E\)。
最后只需要拿 \(T\) 在 AC 自动机上跑一遍,注意处理 \(T[1:i]\) 中已经出现一个 \(t\) 的情况。
将每个 \(E\) 表示为 \(n\) 个变量的线性组合复杂度为 \(O(n^2mc)\),高斯消元复杂度为 \(O(n^3)\),总复杂度为 \(O(n^2mc+n^3+|T|)\)。

浙公网安备 33010602011771号