(mathcal{Description})
Link.
一个游戏包含若干次卡牌抽取,每次以 (p_l) 的概率得到 (+1),(p_d) 的概率得到 (-1),否则得到 (0),操作后以 (p) 的概率结束游戏,求每次抽取后,满足 (+1) 数量大于 (-1) 数量的抽取轮数的期望值。不取模。
(0<ple1),(0le p_l,p_d,p_l+p_dle 1)。
(mathcal{Solution})
我请愿为Tiw 太阳神教的教徒。(
令 (p_e=1-p_l-p_r),表示得到 (0) 的概率。我们直接从答案 (mathcal A) 入手:
即枚举一个抽取后(不一定结束)的状态。此后,把 ((1-p)) 的指数分配到其余三个因子上,令
带入 (mathcal{A}),同时发现 (e) 的限制较少,所以单独枚举 (e),有
最后的级数形如 (sum_{ige 0}inom{i+t}{i}x^i=frac{1}{(1-x)^t}),当 (p_e=1) 时认为 (frac{1}{0^0}=1),即任意 (p_e) 在这个 GF 的收敛域中,可以直接带入。所以
按照先前的套路分配指数,再令
代入整理,得到
我们固定 (l),挑出此时 (d) 的和式来研究,记
错位相减,左右乘 ((1-p_d'')),对齐求和指标 (d) 以化简,最终得到
令 (a_l=inom{2(l-1)}{l-1}p_d''^{l-1}-inom{2l-1}{l-1}p_d''^l),自然得到
代回 (mathcal{A}),交换求和指标并分配 ((1-p_d'')^{l-i+1}) 的指数:
注意到最后的级数是等比数列求和,先考虑它的收敛性:
收敛啦。不妨令 (q=frac{p_l''}{1-p_d''}),整理式子:
最后的最后,研究级数 (sum_{ige0}inom{2i}{i}) 和 (sum_{ige0}inom{2i-1}{i})。考虑到 Catalan 数的 GF:
利用位移和求导消掉分母,得到 (F(x)=sum_{ige0}inom{2i}{i}x^i) 的封闭形式:
接着用 (F(x)) 配凑出 (G(x)=sum_{ige0}inom{2i}{i+1}x^i),结果是
将结果代入 (mathcal{A}):
能直接 (mathcal O(1)) 计算啦。顺便检查一下 ((1-4p_d''p_l'')) 能否开根。注意到 (p_d''+p_l''le 1),所以
能开根,计算即可。注意特判 (p=1) 和 (p_l=0) 的情况(不然会爆 nan
qwq)。
(mathcal{Code})
/*~Rainybunny~*/
#include <cmath>
#include <cstdio>
#include <cassert>
#define rep( i, l, r ) for ( int i = l, rep##i = r; i <= rep##i; ++i )
#define per( i, r, l ) for ( int i = r, per##i = l; i >= per##i; --i )
const int N = 1e7;
double pl, pd, pe, p, f[N + 5], g[N + 5];
inline void solve() {
if ( p == 1 ) return void( printf( "%.12f
", pl ) );
if ( pl == 0 ) return void( printf( "%.12f
", 0. ) );
double c = pe * ( 1 - p ), // pe'
a = ( 1 - p ) * pl / ( 1 - c ), // pl''
b = ( 1 - p ) * pd / ( 1 - c ), // pd''
q = a / ( 1 - b ), r = a * b, // pl''/(1-pd''); pl''pd''
u = 1 / sqrt( 1 - 4 * r );
printf( "%.12f
", q / ( 1 - p ) / ( 1 - c ) / ( 1 - q )
* ( !a || !b ? 1 : ( u - b / ( 2 * r ) * ( u - 1 ) ) ) );
}
int main() {
freopen( "augury.in", "r", stdin );
freopen( "augury.out", "w", stdout );
int T;
scanf( "%*d %d", &T );
while ( T-- ) {
scanf( "%lf %lf %lf", &pl, &pd, &p ), pe = 1 - pl - pd;
solve();
}
return 0;
}