考虑建出AC自动机。则问题相当于,我们每步会从节点(i)等概率地走向( ext{trans}(i,0))或( ext{trans}(i,1))。给定了一个起点和若干个终点,求从每个终点结束的概率。
因为到达一个终点后游戏就结束了,我们不会继续走,所以每个终点被经过的次数要么是(0),要么是(1)。因此,从每个终点结束的概率,在数值上就等于它被经过的期望次数。
设(E_{i})表示经过AC自动机上节点(i)被经过的期望次数。则有转移:
因为AC自动机的节点数是(O(nm))的,所以用高斯消元解上述方程组的时间复杂度是(O(n^3m^3))。无法承受。
考虑优化。发现我们并不关心除若干个终点外的其它节点的(E)值。而终点的数量只有(O(n))级别。
设(E_0)表示所有非终点节点的期望经过次数之和,(E_i)表示第(i)个终点的期望经过次数。
首先,因为最终必定会从某个终点出去(也就是游戏必有一个赢家),所以(sum_{i=1}^{n}E_i=1)。
考虑从任意一个非终点节点出发,按照第(i)个人给定的硬币序列,依次经过(m)条转移边,最后一定能走到第(i)个终点。所以我们初步认为(E_i=frac{1}{2^m}E_0)。但是这样等于是说所有人获胜的概率一样大,显然不对。
这样做的问题在于,有可能在你走这(m)步的路径上,还没走到你想要去的终点(i),就半路遇上了另一个终点(j),游戏立刻终止,于是你就无法到达(i)了!所以(frac{1}{2^m}E_0)这个期望,不能全贡献到(E_i)上,也会贡献到中途经过的节点上。
发现这种情况发生时,一定是存在一个(1leq k<m),使得串(i)的一个长为(k)的前缀,等于串(j)的一个长为(k)的后缀。并且在你出发的这个非终点节点上,(j)已经匹配好了前(m-k)位。接下来你按(i)的序列走,只要走出了前(k)位,立刻就被终点(j)截胡。需要特别注意的是,(i)可能等于(j)。
综上,我们对每个(i)可以列出方程:
判断(operatorname{pre}(i,k)=operatorname{suf}(j,k))可以用后缀数组或哈希简单实现。
加上前面列出的(sum_{i=1}^{n}E_i=1)这个方程。我们一共有(n+1)个方程,(n+1)个未知数,直接高斯消元即可。
时间复杂度(O(n^3))。