Loading

题解: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)\) 秒匹配上,那么有:

\[\begin{aligned} E(x)=\begin{cases} 0&,x为终止结点\\ \displaystyle\sum_{i=1}^cp_iE(tran(x,i))+1&,O.W. \end{cases} \end{aligned} \]

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|)\)

posted @ 2025-06-07 08:24  complexor  阅读(15)  评论(0)    收藏  举报