有n个开关,一开始状态都为关闭。每次随机选出一个开关将其状态改变,选出第i个开关的几率为${ p_i \over \sum_{i=1}^n p_i} $,求状态第一次变为s的操做步数。函数
考虑先从组合方法入手。
最基本的思路就是枚举一种一定结束的状态,可是这样的状态不必定合法,由于这个状态的前缀可能已经结束了,因此咱们能够容斥若干个前缀,强制这些前缀已经结束,来算出这个状态中没有一个前缀可以结束的方案数。
固然,在枚举的过程当中,"一种状态"能够经过枚举每个开关的操做次数\(x_i\),再将这些操做次数排列起来,咱们枚举前缀的时候,一样枚举每一个开关的操做次数,那么咱们能够写出答案的式子:
\[\sum_{x_i} \prod [2|x_i-s_i] \prod q_i^{x_i} \sum_{i=1}^nx_i \sum_{m=0}^{\infty} \sum_{y_{1i};\exists i,y_{1i}>0 } \sum_{y_{2i};\exists i,y_{2i}>0 }... \sum_{y_{mi};\exists i, y_{mi}>0 } \sum_{{z_i};\exists i,z_i>0 }\\ \prod [2|y_{ij}] \prod_{j}[\sum_{i=1}^m y_{ij} +z_i = x_i] (-1)^m {(\sum_{i=1}^m z_i)! \over \prod_{i=1}^n z_i!}\prod_{i=1}^m {(\sum_{j=1}^n y_{ij})! \over \prod_{j=1}^n y_{ij}} \]
\(q_i\)为\(p_i \over \sum p_i\)spa
看起来十分复杂,其实有不少能够化简的地方,为了保证题解的简洁性,这里不一一赘述。上述式子最难化简的莫过因而\(\sum x_i\),这个实际上是一个带权方案数,在算的时候咱们能够认为是计算$[y^1]\prod_{i=1}^n (1+x_iy) $,因此只须要记常数项与一次项系数。code
用指数型生成函数来表示,能够方便的获得答案式子:
\[F(x)=\prod (e^{q_ix} + q_ixye^{q_ix} +(-1)^{s_i} e^{-q_ix} - (-1)^{s_i} xye^{-q_ix}) \\ =\sum_{i=0}^{\infty} {f_{1i} \over i!}x^i + {f_{2i} \over i!}x^iy\]get
\[G(x)=\prod (e^{q_ix} + q_ixye^{q_ix} + e^{-q_ix} -xye^{-q_ix}) \\ =\sum_{i=0}^{\infty}{g_{1i} \over i!}x^i + {g_{2i} \over i!}x^iy\]io
记\(f_0(x)=\sum_{i=0}^{\infty}f_{0i}x^i,f_1(x)=\sum_{i=0}^{\infty}f_{1i}x^i,f(x)=f_0(x)+f_1(x)y\)
\(g_0(x)=\sum_{i=0}^{\infty}g_{0i} x^i,g_1(x)=\sum_{i=0}^{\infty}g_{1i}x^i,g(x)=g_0(x)+g_1(x)y\)
以\(F(x)\)为例,\(F(x)=\sum_{i=- \infty}^{\infty} a_i e^{ix} + b_i xy e^{ix}\)
能够获得\(f(x)=\sum_{i=- \infty}^{\infty} {a_i \over 1-ix}+{b_i x\over (1-ix)^2}\)
答案为
\[\lim_{x \to 1 }[y^1]f(x)\sum_{m=0}^{\infty}(-g(x)+1)^m=\lim_{x \to 1}[y^1]{f(x) \over g(x)}\\ ={f_2(x)g_1(x) -g_2(x)f_1(x) \over g_1^2(x)}\]
咱们发如今\(g_1(x)\)中有\(\frac {1} {1-x}\)的项,在\(f_2(x),g_2(x)\)有\(\frac {1} {(1-x)^2}\)的项,因此咱们发现,答案的分子有三阶无穷大的项,分母有二阶无穷大的项。
那么是否意味着答案发散呢?偏偏相反,由于感性理解答案确定是收敛的,因此咱们有理由认为分子上三阶无穷大的系数为0,而事实也确实如此,由于\(f_2(x)与g_2(x)\)的\(1 \over (1-x)^2\)项系数相同,\(f_1(x)与g_1(x)\)的\(1 \over 1-x\)项的系数也相同,咱们计算答案,只须要计算分子的二阶无穷大的值除以分母的二阶无穷大的值便可,又由于两个无穷大都为\({1\over (1-x)^2}\),因此是能够约去的。class
这种作法与网上的大体相同,可是在处理\(\sum x_i\)项的时候不太同样,网上题解大可能是用的求导来解决第i项对答案的贡献为i的问题,而本文观察到了\(\sum x_i = [y^1]\prod (1+x_iy)\)的性质。这种作法无疑具备比较高的扩展性,例如操做开关i须要\(a_i\)的代价,求代价的指望,求导方法便显得十分无力,而这个方法只须要将原式稍稍更改为\(\sum a_i x_i = [y^1]\prod (1+a_ix_iy)\)便可。
code扩展