[概率与期望] Codeforces 1623D Robot Cleaner Revisit

题目大意

\(n\times m\) 的网格上有一个扫地机器人位于 \((x_1,y_1)\),有一个垃圾位于 \((x_2,y_2)\)。初始时速度为 \(dx=1,dy=1\) ,若机器人位于 \((x,y)\),则下一秒机器人将位于 \((x+dx,y+dy)\)。若机器人碰壁则速度方向变为反弹的方向。若机器人和垃圾位于同一行或同一列,有 \(p\%\) 的概率清理掉垃圾,有 \(1-p\%\) 的概率不清理。求扫地机器人清理掉垃圾的期望时间。\(n\cdot m\leq 10^5\)

题解

机器人的移动存在周期 \(C=\mathrm{lcm}(2(n-1),2(m-1))=\frac{2(n-1)(m-1)}{\gcd(n-1,m-1)}\)

在一个周期内,设走了 \(i-1\) 步仍未清理掉垃圾的概率为 \(a_i\),走了 \(i\) 步才刚好清理掉垃圾的概率为 \(b_i\),则 \(a_i\)\(b_i\) 我们可以通过暴力一个周期算出。最后有:

\[ans=\sum_{t=0}^\infty a_C^t\sum_{i=1}^C (i+tC)\times b_i\\ =\sum_{t=0}^\infty a_C^t\sum_{i=1}^C(ib_i+tCb_i)\\ =\left(\sum_{i=1}^C ib_i\right)\left(\sum_{t=0}^\infty a_C^t\right)+C\left(\sum_{i=1}^C b_i\right)\left(\sum_{t=0}^\infty ta_C^t\right)\\ =\left(\sum_{i=1}^C ib_i\right)\frac{1}{1-a_C}+C\left(\sum_{i=1}^C b_i\right)\frac{a_C}{(1-a_C)^2} \]

Code

#include <bits/stdc++.h>
using namespace std;

#define LL long long

const LL MOD = 1e9 + 7;
LL a[200010], b[200010], p;
int T, n, m, X1, Y1, X2, Y2;

LL qpow(LL b, LL n) {
    LL x = 1, Power = b % MOD;
    while (n) {
        if (n & 1) x = x * Power % MOD;
        Power = Power * Power % MOD;
        n >>= 1;
    }
    return x;
}

int main() {
    cin >> T;
    while (T--) {
        cin >> n >> m >> X1 >> Y1 >> X2 >> Y2 >> p;
        LL C = 2LL * (n - 1) / __gcd(n - 1, m - 1) * (m - 1);
        p = p * qpow(100, MOD - 2) % MOD;
        int dx = 1, dy = 1;
        a[0] = 1;
        LL sum_ib = 0, sum_b = 0;
        for (int i = 1;i <= C;++i) {
            LL sgn = (X1 == X2 || Y1 == Y2);
            a[i] = a[i - 1] * (1LL - sgn * p) % MOD;
            a[i] = (a[i] % MOD + MOD) % MOD;
            if (X1 + dx<1 || X1 + dx>n) dx *= -1;
            if (Y1 + dy<1 || Y1 + dy>m) dy *= -1;
            X1 += dx; Y1 += dy;
            if (X1 == X2 || Y1 == Y2) b[i] = a[i] * p % MOD;
            else b[i] = 0;
            sum_ib = (sum_ib + b[i] * i % MOD) % MOD;
            sum_b = (sum_b + b[i]) % MOD;
        }
        LL t = qpow((MOD + 1 - a[C]), MOD - 2);
        LL temp1 = sum_ib % MOD * t % MOD;
        LL temp2 = C * sum_b % MOD * a[C] % MOD * t % MOD * t % MOD;
        LL ans = (temp1 + temp2) % MOD;
        cout << ans << endl;
    }
    return 0;
}
posted @ 2021-12-29 13:30  AE酱  阅读(233)  评论(4编辑  收藏  举报