P6858 深海少女与胖头鱼

知识点:概率期望,DP

P6858 深海少女与胖头鱼

原题面:Luogu


我不会期望/cy

草好久没打炉石了,回去搓一把。


题意简述

对面有 \(n\) 只带有「圣盾」的「鲭鱼圣者」,\(m\) 只不带「圣盾」的「鲭鱼圣者」。
每次可以等概率地对场上一只「鲭鱼圣者」造成伤害。
「圣盾」可以抵挡一次伤害,可以立即杀死不带「圣盾」的「鲭鱼圣者」。
每当一个「鲭鱼圣者」失去「圣盾」时,其他 所有存活的「鲭鱼圣者」都会获得「圣盾」。
求杀死所有「鲭鱼圣者」的其期望攻击次数 \(\bmod 998244353\) 的值。

\(1\le n\le 10^{14}\)\(0\le m\le 10^6\)
保证答案的形式 \(\frac{p}{q}\) 满足 \((p,q\in \mathbf{N}\)\(998244353\nmid q)\)
1S,128MB。


分析题意

先考虑 \(m=0\) 的情况,显然此时场上没有盾的鱼人最多只有 1 条。
考虑 DP,设 \(f_{n,0/1}\) 表示干掉 \(n\) 条带盾的鱼人,\(0/1\) 条不带盾的鱼人所需攻击次数的期望。

显然有:\(f_{0,0} = 0\)\(f_{0,1} = 1\)

转移时考虑从一个状态攻击一次能达到的状态,有:

\[\begin{aligned} f_{i,0} &= f_{i-1,1} + 1\\ f_{i,1} &= \frac{i}{i+1} \times (f_{i,1} +1)+ \frac{1}{i+1} \times (f_{i,0} + 1) \end{aligned}\]

对于一式的情况,此时只能攻击一个带盾的鱼人,削除该鱼人的盾。其攻击次数为削除该鱼人的盾后需要的次数 + 1。

对于二式的情况,若以 \(\frac{i}{i+1}\) 的概率攻击了一条带有圣盾的鱼人,还会转移到相同的状态。
若以 \(\frac{1}{i+1}\) 的概率攻击了不带盾的鱼人,则会转移到削除该鱼人的状态。


发现上面的方程转移不来,化下二式:

\[\begin{aligned} f_{i,1} &= \frac{i}{i+1} \times (f_{i,1} +1)+ \frac{1}{i+1} \times (f_{i,0} + 1)\\ i\times f_{i,1} + f_{i,1} &= i\times f_{i,1} + f_{i,0} + i + 1\\ f_{i,1} &= f_{i,0} + i + 1 \end{aligned}\]

得到了 \(f_{i,1}\)\(f_{i,0}\) 的关系。 再将一式代入,有:

\[f_{i,1} = f_{i-1,1} + i + 2 \]

显然是一个等差数列求和的形式,由 \(f_{0,1} = 1\),则有(具体推导过程见最后):

\[\begin{aligned} f_{i,1} &= \frac{i(i+5) + 2}{2}\\ f_{i,0} &= f_{i,1} - i - 1 = \frac{i(i+3)}{2} \end{aligned}\]

预处理 2 的逆元后,可以 \(O(1)\) 地求得 \(m=1\) 时的答案 \(f_{n,0}\) 了。


再推广到 \(m\not = 1\) 的情况。
更一般性地,设 \(f_{n,m}\) 表示干掉 \(n\) 条带盾的鱼人,\(m\) 条不带盾的鱼人所需攻击次数的期望。
由上显然有:

\[f_{n,m} = \dfrac{n}{n+m}\times (f_{n+m-1,1} +1) + \dfrac{m}{n+m}\times (f_{n,m-1} + 1) \]

上式中的前一项 \(f_{n+m-1,1}\) 可以 \(O(1)\) 求,后面一项可以递推。
每次都 \(O(\log p)\) 地求逆元,总复杂度 \(O(m\log p)\)


爆零小技巧

等差数列求和公式:

\[\begin{aligned} S_n &= \frac{n(a_1+a_n)}{2}\\ &= na_1 + \frac{n(n-1)d}{2} \end{aligned}\]

注意 \(n\le 10^{18}\),需要先令 \(n\bmod 998244353\),否则必爆 LL。


代码实现

//知识点:概率期望,等差数列 
/*
By:Luckyblock
*/
#include <cctype>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define LL long long
const int kMaxm = 1e6 + 10;
const LL kMod = 998244353ll;
//=============================================================
LL n, m, inv2, f[kMaxm];
//=============================================================
inline LL read() {
  LL f = 1, w = 0; char ch = getchar();
  for (; !isdigit(ch); ch = getchar()) if (ch == '-') f = -1;
  for (; isdigit(ch); ch = getchar()) w = (w << 3ll) + (w << 1ll) + (ch ^ '0');
  return f * w;
}
LL QPow(LL x_, LL y_) {
  LL ret = 1;
  for (; y_; y_ >>= 1ll) {
    if (y_ & 1) ret = ret * x_ % kMod;
    x_ = x_ * x_ % kMod;
  }
  return ret;
}
LL fx0(LL x_) {
  x_ %= kMod;
  return x_ * (x_ + 3ll) % kMod * inv2 % kMod;
}
LL fx1(LL x_) {
  x_ %= kMod;
  return (x_ * (x_ + 5ll) % kMod + 2ll) * inv2 % kMod;
}
//=============================================================
int main() {
  n = read() % kMod, m = read();
  inv2 = QPow(2ll, kMod - 2);
  f[0] = fx0(n);
  for (int i = 1; i <= m; ++ i) {
    LL inv = QPow(n + i, kMod - 2) % kMod;
    LL fni = fx1(n + i - 1);
    f[i] = n * inv % kMod * fni % kMod;
    f[i] = (f[i] + i * inv % kMod * f[i - 1] % kMod + 1) % kMod;
  }
  printf("%lld\n", f[m]);
  return 0;
}

某数列忘干净的 sb 的推导

以下是数列忘干净的傻逼的有误推导 = =

\[\begin{aligned} f_0 &= 1\\ f_n &= f_{n-1} + n + 2\\ \\ f_{n} + f_0 &= \sum_{i=1}^{n} i + 2n\\ f_{n} &= n + \frac{n(n-1)}{2} + 2n - 1\\ f_{n} &= \frac{n(n-1+2+4)-2}{2}\\ f_{n} &= \frac{n(n+5)-2}{2}\\ \end{aligned}\]

\[\begin{aligned} f_0 &= 1\\ f_1 &= f_0 + 1 + 2 = 4\\ f_2 &= f_1 + 2 + 2 = 8\\ \\ \dfrac{2\times 7 - 2}{2} &= 6\not ={8} \end{aligned}\]

https://pic.downk.cc/item/5fa2771f1cd1bbb86b1c8aed.jpg

???我哪错了???

以上是数列忘干净的傻逼的有误推导 = =


关于 \(f_n=\frac{n(n+5) + 2}{2}\)

已知:

\[\begin{aligned} f_n &= f_{n-1} + n + 2\\ f_{n-1} &= f_{n-2} + n - 1 + 2\\ &\cdots\\ f_2 &= f_1 + 2 + 2\\ f_1 &= f_0 + 1 + 2\\ f_0 &= 1 \end{aligned}\]

左右两边分别求和,则有:

\[\begin{aligned} &f_{0} + f_1 + \cdots + f_{n-1} + f_n\\ = 1 + &f_0 + f_1 + \cdots + f_{n-1} + (1 + 2 +\cdots + n) + 2\times n \end{aligned}\]

对应项相消,有:

\[\begin{aligned} f_n&= 1 +\sum_{i=1}^{n}{i} + 2n\\ &= 1 + n + \dfrac{n(n-1)}{2} + 2n\\ &= \frac{n(n+5) + 2}{2} \end{aligned}\]

posted @ 2020-11-04 17:42  Luckyblock  阅读(175)  评论(2编辑  收藏  举报