概率期望训练之一

solution by jklover%%%

为什么要写两个转移方程呢?

因为一个是O(N^2)

如果联立之后呢?

O(N)的

code by std:

#include <cstdio>
using ll = long long;
constexpr int MOD = 998244353;
inline int quick_pow(int a, int n)
{
    int res = 1;
    while (n)
    {
        if (n & 1)
            res = (ll)res * a % MOD;
        a = (ll)a * a % MOD;
        n >>= 1;
    }
    return res;
}
int fact[1000005], inv[1000005], ans[1000005];
inline int binom(int n, int m)
{ return (ll)fact[n] * inv[m] % MOD * inv[n - m] % MOD; }
int main()
{
    int n, a, b;
    scanf("%d%d%d", &n, &a, &b);
    fact[0] = 1;
    for (int i = 1; i <= n; i++)
        fact[i] = (ll)fact[i - 1] * i % MOD;
    inv[n] = quick_pow(fact[n], MOD - 2);
    for (int i = n; i; i--)
        inv[i - 1] = (ll)inv[i] * i % MOD;
    int p = (ll)a * quick_pow(b, MOD - 2) % MOD,
        q = (1 - p + MOD) % MOD, out = 0;
    auto func = [&] (int x) { return (quick_pow(p, x) - quick_pow(q, x) + MOD) % MOD; };
    ans[0] = 1;
    for (int i = 1, cur = 1; i < n; i++, cur = ((ll)cur * cur + 2) % MOD)
    {
        if (a * 2 == b)
            ans[i] = (ll)binom(n, i) * quick_pow(p, (ll)i * (n - i) % (MOD - 1)) % MOD;
        else
            ans[i] = (ll)ans[i - 1] * func(n - i + 1) % MOD *
                     quick_pow(func(i), MOD - 2) % MOD;
        out = (out + (ll)ans[i] * cur) % MOD;
    }
    printf("%d\n", out);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/wzxbeliever/p/11674034.html