题解 P6858 【深海少女与胖头鱼】
这道题目是一道计算期望的题目,但是不要害怕,只要先从特殊情况入手,就不难了,而对于这道题来说,就可以先从
设
当
当
继续推,则有
这个显然可以用一个二次函数来表示
令
当
进一步,得
这样,最终得到:
然后记住随时取模即可。
递归版代码如下:
#include<cstdio>
#define ll long long
using namespace std;
const ll MOD = 998244353;
ll quickpow(ll a, ll b) {ll res = 1; for (; b; b >>= 1, a = a * a % MOD) if (b & 1) res = res * a % MOD; return res;}
ll calc(ll x) {return ((x * x + x * 5 + 2) / 2) % MOD;}
ll f(ll n, ll m) {
if (!m) return (f(n - 1, 1) + 1) % MOD; if (m == 1) return calc(n);
return ((n * quickpow(n + m, MOD - 2)) % MOD * calc(n + m - 1) % MOD + (m * quickpow(n + m, MOD - 2)) % MOD * f(n, m - 1) + 1) % MOD;
}
ll n, m;
int main() {
scanf("%lld%lld", &n, &m);
return 0 & printf("%lld", f(n % MOD, m));
}
非递归版代码如下:
#include<cstdio>
#define ll long long
using namespace std;
const ll MOD = 998244353;
ll quickpow(ll a, ll b) {ll res = 1; for (; b; b >>= 1, a = a * a % MOD) if (b & 1) res = res * a % MOD; return res;}
ll calc(ll x) {return ((x * x + x * 5 + 2) / 2) % MOD;}
ll frac(ll x, ll y) {return (x * quickpow(y, MOD - 2)) % MOD;}
ll n, m, ans;
int main() {
scanf("%lld%lld", &n, &m), n %= MOD, ans = calc(n);
if (!m) return 0 & printf("%lld", (calc(n - 1) + 1) % MOD);
for (ll i = 2; i <= m; ++i) ans = (frac(n, n + i) * calc(n + i - 1) + frac(i, n + i) * ans + 1) % MOD;
return 0 & printf("%lld", ans);
}