LOJ 2004 100pts
首先我们肯定要建AC自动机的。。
那么这题就肯定是个AC自动机上\(dp\)。
所以想想状态。
首先如果我们把状态设成这样行不行:
\(dp(i)\)表示匹配到了i节点的概率。
那么转移的时候就是\(dp(i)=frac{1}{2}\sum dp(go_i^c)\)。
这样的转移是有环的。。。所以高斯消元。。。
但是!AC自动机的节点数是\(O(n^2)\)的。。。
所以T得飞起。。
那么试着改一改?
改为\(dp(i)\)直接表示第i个串第一次出现的概率?
那么转移很难啊。
如果我们当前的串为\(S\),并且没有任何的串在其中出现过,设所有的\(S\)的概率综合为\(fail\)。
那么我们在\(S\)后硬生生地加上\(s_i\),那么这个概率是\(fail\times frac{1}{2}^m\)。
但是可能中间会有某个\(s_j\)出现。
那么现在的串可以变形成\(S\)的一个前缀\(+s_j+s_i\)的一个后缀
其中\(s_i\)的一个前缀和\(s_j\)的一个后缀匹配。(这不就是\(fail\)指针吗!
其中的概率是\(dp(j)\times frac{1}{2}^{len(suf(s_i))}\)。
所以转移方程就出来了。
但是。。。这个还是有环的。。。所以高斯消元。。。
可惜我们只有\(n\)个方程,却有\(n+1\)个未知数。
但注意到所有串第一次出现的概率之和为\(1\)就释然了。
做完了。。。