zoukankan      html  css  js  c++  java
  • Solution -「多校联训」光影交错

    (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) 入手:

    [mathcal{A} = sum_{l>dge 0,ege 0} inom{l+d+e}{l,d,e} p_l^lp_d^dp_e^e (1-p)^{l+d+e-1}, ]

    即枚举一个抽取后(不一定结束)的状态。此后,把 ((1-p)) 的指数分配到其余三个因子上,令

    [egin{cases} p_e'=p_e(1-p)\ p_l'=p_l(1-p)\ p_d'=p_d(1-p) end{cases}, ]

    带入 (mathcal{A}),同时发现 (e) 的限制较少,所以单独枚举 (e),有

    [egin{aligned} mathcal{A} &=frac{1}{1-p} sum_{l>dge0,ege0} inom{l+d+e}{l,d,e}p_e'^ep_d'^dp_l'^l\ &= frac{1}{1-p} sum_{lge dge 0} inom{l+d}{d} p_l'^lp_d'^d sum_{ege 0}inom{l+d+e}{e}p_e'^e. end{aligned} ]

      最后的级数形如 (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 的收敛域中,可以直接带入。所以

    [mathcal{A} = frac{1}{1-p} sum_{l>dge0} inom{l+d}{d}p_l'^lp_d'^d frac{1}{(1-p_e')^{l+d+1}}. ]

      按照先前的套路分配指数,再令

    [egin{cases} p_l''=frac{p_l'}{1-p_e'}\ p_d''=frac{p_d'}{1-p_e'} end{cases}, ]

    代入整理,得到

    [mathcal{A}=frac{1}{(1-p)(1-p_e')} sum_{l>dge0} inom{l+d}{d} p_l''^lp_d''^d. ]

      我们固定 (l),挑出此时 (d) 的和式来研究,记

    [S_d(l)=sum_{0le d<l}inom{l+d}{d}p_d''^d. ]

    错位相减,左右乘 ((1-p_d'')),对齐求和指标 (d) 以化简,最终得到

    [(1-p_d'')S_d(l)=S_d(l-1)+inom{2(l-1)}{l-1}p_d''^{l-1}-inom{2l-1}{l-1}p_d''^l. ]

    (a_l=inom{2(l-1)}{l-1}p_d''^{l-1}-inom{2l-1}{l-1}p_d''^l),自然得到

    [S_d(l) = sum_{i=0}^l frac{a_i}{(1-p_d'')^{l-i+1}}. ]

      代回 (mathcal{A}),交换求和指标并分配 ((1-p_d'')^{l-i+1}) 的指数:

    [egin{aligned} mathcal{A} &= frac{1}{(1-p)(1-p_e')} sum_{lge0} p_l''^l sum_{i=1}^l frac{a_i}{(1-p_d'')^{l-i+1}} \ &= frac{1}{(1-p)(1-p_e')} sum_{ige1} frac{a_i}{(1-p_d'')^{-i+1}} sum_{lge i} left(frac{p_l''}{1-p_d''} ight)^l. end{aligned} ]

    注意到最后的级数是等比数列求和,先考虑它的收敛性:

    [egin{aligned} 1-p_d''-p_l'' &= 1-frac{(1-p)p_d+(1-p)p_l}{1-(1-p)p_e} \ &= frac{1-(1-p)p_e-(1-p)p_d-(1-p)p_l}{1-(1-p)p_e} \ &= frac{p}{1-(1-p)p_e} \ &>0. end{aligned} ]

    收敛啦。不妨令 (q=frac{p_l''}{1-p_d''}),整理式子:

    [egin{aligned} mathcal{A} &= frac{1}{(1-p)(1-p_e')} sum_{ige1}frac{a_i}{(1-p_e'')^{-i+1}}cdot frac{q^i}{1-q} \ &= frac{1}{(1-p)(1-p_e')(1-q)} sum_{ige1} q^i left{ inom{2(i-1)}{i-1}[p_d''(1-p_d'')]^{i-1} - p_d''inom{2i-1}{i-1}[p_d''(1-p_d'')]^{i-1} ight} \ &= frac{q}{(1-p)(1-p_e')(1-q)} sum_{ige1} left[ inom{2(i-1)}{i-1}(p_d''p_l'')^{i-1} - p_d''inom{2i-1}{i-1}(p_d''p_l'')^{i-1} ight]. end{aligned} ]

      最后的最后,研究级数 (sum_{ige0}inom{2i}{i})(sum_{ige0}inom{2i-1}{i})。考虑到 Catalan 数的 GF:

    [egin{aligned} C(x) &= sum_{ige0}frac{inom{2i}{i}}{i+1}x^i\ &= frac{1-(1-4x)^{frac{1}{2}}}{2}, end{aligned} ]

    利用位移和求导消掉分母,得到 (F(x)=sum_{ige0}inom{2i}{i}x^i) 的封闭形式:

    [egin{aligned} lbrack xC(x) brack' &= left[ frac{1-(1-4x)^{frac{1}{2}}}{2} ight]' \ &= (1-4x)^{-frac{1}{2}} \ &= F(x). end{aligned} ]

    接着用 (F(x)) 配凑出 (G(x)=sum_{ige0}inom{2i}{i+1}x^i),结果是

    [G(x)=frac{1-(1-4x)^{frac{1}{2}}}{2x}. ]

      将结果代入 (mathcal{A})

    [mathcal{A} = frac{q}{(1-p)(1-p_e')(1-q)}left{ (1-4p_d''p_l'')^{-frac{1}{2}} - frac{1}{2p_l''}left[ (1-4p_d''p_l'')^{-frac{1}{2}}-1 ight] ight} ]

    能直接 (mathcal O(1)) 计算啦。顺便检查一下 ((1-4p_d''p_l'')) 能否开根。注意到 (p_d''+p_l''le 1),所以

    [egin{aligned} p_d''p_l''&le frac{(p_l''+p_r'')^2}{4}\ &le frac{1}{4}. end{aligned} ]

    能开根,计算即可。注意特判 (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;
    }
    
    
  • 相关阅读:
    Trie树
    递归函数两种方式的区别
    揭开HTTPS的神秘面纱
    补码到底是个什么东西
    浮点数的运算精度丢失
    PHP的stdClass
    2019-10-24
    MySQL存储引擎
    代码整洁之道小结
    NFS4 挂载同主机多个目录
  • 原文地址:https://www.cnblogs.com/rainybunny/p/15018390.html
Copyright © 2011-2022 走看看