zoukankan      html  css  js  c++  java
  • 2016北京集训测试赛(十)Problem A: azelso

    Descrpition

    Solution

    我们把遇到一个旗子或者是遇到一个敌人称为一个事件.
    这一题思路的巧妙之处在于我们要用(f[i])表示从(i)这个事件一直走到终点这段路程中, (i)(i + 1)这段路只被经过一次的概率. 分类讨论:

    • (i + 1)是一个敌人, 则(f[i] = f[i + 1] imes p[i + 1])
    • (i + 1)是一个旗子, 则

    [f[i] = f[i + 1] \ + f[i + 1] imes (1 - f[i + 1]) imes p[i + 1] \ + f[i + 1] imes (1 - f[i + 1]) imes p[i + 1] imes (1 - f[i + 1]) imes p[i + 1] \ + ... \ + f[i + 1] imes (1 - f[i + 1])^infty imes p[i + 1]^infty ]

    表示(i + 1)(i + 2)这一段只被走一次的概率, 加上走过(i + 1)后掉回(i + 1), 再往后走, 再掉回(i + 1), 一直循环, 一直掉回(i + 1), 直到走到终点的概率. 上面的式子用无限和式稍微处理即可化简.

    然后我们又发现一段路程的被走过的期望次数等于(1 / p_i), 因此就可以方便地统计总共要走的期望距离.

    #include <cstdio>
    #include <cctype>
    
    namespace Zeonfai
    {
        inline long long getInt()
        {
            long long a = 0, sgn = 1; char c;
            while(! isdigit(c = getchar())) if(c == '-') sgn *= -1;
            while(isdigit(c)) a = a * 10 + c - '0', c = getchar();
            return a * sgn;
        }
        inline char getChar()
        {
            char c;
            while(! isgraph(c = getchar()));
            return c;
        }
    }
    const long long MOD = 1e9 + 7, N = 1e5;
    inline long long getInverse(long long a)
    {
        long long res = 1;
        for(long long x = MOD - 2; x; a = a * a % MOD, x >>= 1) if(x & 1) res = res * a % MOD;
        return res;
    }
    int main()
    {
    
        #ifndef ONLINE_JUDGE
    
        freopen("azelso.in", "r", stdin);
        freopen("azelso.out", "w", stdout);
    
        #endif
    
        using namespace Zeonfai;
        long long len = getInt(), n = getInt();
        static long long opt[N + 2], pos[N + 2], E[N + 2], p[N + 2];
        for(long long i = 1; i <= n; ++ i)
        {
            opt[i] = getChar() == 'F' ? 0 : 1;
            pos[i] = getInt() % MOD;
            long long a = getInt(), b = getInt(); p[i] = a * getInverse(b) % MOD;
        }
        E[n] = 1;
        for(long long i = n - 1; ~ i; -- i) E[i] = opt[i + 1] == 0 ? (E[i + 1] - p[i + 1] * E[i + 1] % MOD + p[i + 1] + MOD) % MOD : E[i + 1] * getInverse(p[i + 1]) % MOD;
        long long ans = 0; pos[0] = 0; pos[n + 1] = len;
        for(long long i = 0; i <= n; ++ i)
            ans = (ans + (pos[i + 1] - pos[i] + MOD) * E[i] % MOD) % MOD;
        // ans = (ans + len - pos[n]) % MOD;
        printf("%d
    ", ans);
    }
    
    
  • 相关阅读:
    分梨
    18岁生日
    马的移动
    摆积木
    杭电2093考试排名
    栈的应用——四则运算表达式求值
    用指针实现对二维数组元素的访问
    用多种方法访问字符数组元素
    fread()函数和fwrite()函数进行文件操作
    hdu-1431 素数回文
  • 原文地址:https://www.cnblogs.com/ZeonfaiHo/p/7404756.html
Copyright © 2011-2022 走看看