精华 推荐

概率与期望

黑大帅 2025-9-17 1:24:13 12 浏览 0 点赞 0 收藏

概率与期望

概率论

事件的运算及概率

  • 包含ABA \subset B,发生 BB 时必然发生 AA,发生 AA 时不一定发生 BB

  • 并(和)事件AB=A+BA \cup B = A + BAA 发生或 BB 发生或两者都发生。

  • 交(积)事件AB=ABA \cap B = ABAABB 同时发生。

  • 差事件AB=AB=AABA - B = A\overline{B} = A - ABAA 发生但 BB 不发生,B\overline{B} 表示 BB 的对立事件。

  • 互斥事件AB=AB=\varnothingAABB 不能同时发生。

  • 对立(逆)事件A+A=S,AA=A+\overline{A}=S,\quad A\overline{A}=\varnothingAA 发生时 A\overline{A} 不发生,A\overline{A} 发生时,AA 不发生。

  • 独立事件P(AB)=P(A)P(B)P(AB)=P(A)P(B)

    AA 发生与否不影响 BB 的概率,反之亦然。

    • A,BA,B 独立,则 A,BA,\overline{B}A,B\overline{A},BA,B\overline{A},\overline{B} 也相互独立。
    • A,B,CA,B,C 相互独立,那么
      • A,B,CA,B,C两两独立(但逆命题不成立)
      • P(ABC)=P(A)P(B)P(C)P(ABC)=P(A)P(B)P(C)
  • 德摩根律

    $$\overline{A\cup B}=\overline{A}\cap\overline{B}\\ \overline{A\cap B}=\overline{A}\cup\overline{B} $$
  • 加法公式(容斥原理)
    P(A+B)=P(A)+P(B)P(AB)P(A+B)=P(A)+P(B)-P(AB)
    P(A+B+C)=P(A)+P(B)+P(C)P(AB)P(AC)P(BC)+P(ABC)P(A+B+C)=P(A)+P(B)+P(C)-P(AB)-P(AC)-P(BC)+P(ABC)

  • 减法公式
    P(AB)=P(A)P(AB)P(A-B)=P(A)-P(AB)

  • 对立事件概率
    P(A)=1P(A)P(\overline{A})=1-P(A)


条件概率与乘法公式

  • 条件概率:在 AA 已发生下 BB 的概率。
    P(BA)=P(AB)P(A)P(B\mid A)=\dfrac{P(AB)}{P(A)}

  • 乘法公式
    P(AB)=P(A)P(BA)=P(B)P(AB)P(AB)=P(A)P(B\mid A)=P(B)P(A\mid B)


全概率公式与贝叶斯公式(包括在 NOI 大纲内但大概率 useless)

  • 全概率公式{Bi}\{B_i\} 为完备事件组):

    P(A)=i=1nP(Bi)P(ABi)P(A)=\sum_{i=1}^{n}P(B_i)P(A\mid B_i)
  • 贝叶斯(逆概)公式

    P(BiA)=P(Bi)P(ABi)P(A)P(B_i\mid A)=\dfrac{P(B_i)P(A\mid B_i)}{P(A)}

离散型随机变量(一维)

离散型随机变量是指取值为可列(通常是有限或可数无限)集合中某些具体数值的随机变量。

分布列

随机变量 XX 可取值:

X1,X2,,XkX_1,X_2,\dots,X_k

各取值对应的概率为:

P{X=X1},P{X=X2},,P{X=Xk}P\{X=X_1\},P\{X=X_2\},\dots,P\{X=X_k\}

分布函数

F(x)=P{Xx}F(x)=P\{X\le x\}。

重要性质 离散型一维随机变量的分布函数可视为前缀和):P{aXb}=F(b)F(a1)P\{a\le X\le b\}=F(b)-F(a-1)

数学期望

E(X)=i=1nxipiE(X)=\sum_{i=1}^{n}x_i p_i

Y=g(X)Y=g(X),则

E(Y)=i=1ng(xi)piE(Y)=\sum_{i=1}^{n}g(x_i)p_i

性质

  • E(c)=c,E(ax+c)=aE(X)+cE(c)=c,\quad E(ax+c)=aE(X)+c

  • E(X±Y)=E(X)±E(Y)E(X\pm Y)=E(X)\pm E(Y)

  • X,YX,Y 独立,则 E(XY)=E(X)E(Y)E(XY)=E(X)E(Y)

方差

D(X)=E(X2)E2(X)D(X)=E(X^2)-E^2(X)

性质

  • D(c)=0,D(aX+b)=a2D(X)D(c)=0,\quad D(aX+b)=a^2D(X)
  • D(x±y)=D(x)+D(y)±2Cov(X,Y)D(x\pm y)=D(x)+D(y)\pm 2\operatorname{Cov}(X,Y),其中
    Cov(X,Y)=E(XY)E(X)E(Y)\operatorname{Cov}(X,Y)=E(XY)-E(X)E(Y)为协方差。
  • X,YX,Y独立,则 Cov(X,Y)=0\operatorname{Cov}(X,Y)=0,因此 D(X±Y)=D(X)+D(Y)D(X\pm Y)=D(X)+D(Y)

常见分布

【0–1 分布(伯努利分布)】

进行一次独立试验,成功的概率为 pp,失败的概率为 1p1-p。(即 n=1n=1 的二项分布)

记作 分布列 数学期望 方差
XB(1,p)X\sim B(1,p) P{X=0}=1p,  P{X=1}=pP\{X=0\}=1-p,\; P\{X=1\}=p E(X)=pE(X)=p D(X)=p(1p)D(X)=p(1-p)

【二项分布】

进行 nn 次独立试验,每次成功的概率为 pp,失败的概率为 1p1-p

记作 分布列 数学期望 方差
XB(n,p)X\sim B(n,p) P{X=k}=(nk)pk(1p)nkP\{X=k\}=\binom{n}{k}p^k(1-p)^{n-k} E(X)=npE(X)=np D(X)=np(1p)D(X)=np(1-p)

【几何分布】

进行独立试验,直到第一次成功为止;成功的概率为 pp,失败的概率为 1p1-p

记作 分布列 数学期望 方差
XG(p)X\sim G(p) P{X=k}=(1p)k1pP\{X=k\}=(1-p)^{k-1}p E(X)=1pE(X)=\dfrac{1}{p} D(X)=1pp2D(X)=\dfrac{1-p}{p^2}

【超几何分布】

NN 个物体中抽取 nn 个物体,其中有 KK 个是成功的,NKN-K 个是失败的。

记作 分布列 数学期望 方差
XH(N,K,n)X\sim H(N,K,n) $P\{X=k\}=\dfrac{\binom{K}{k}\binom{N-K}{n-k}}{\binom{N}{n}}$ E(X)=nKNE(X)=\dfrac{nK}{N} D(X)=nK(NK)(Nn)N2(N1)D(X)=\dfrac{nK(N-K)(N-n)}{N^2(N-1)}

概率与期望 DP

与组合数 DP 类似,只是在 DP 转移时结合概率或期望的计算。常见有后效性方程,需要移项或高斯消元处理。

【例题 1】Jerry's Protest(纯概率论应用)

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n; cin>>n;
    vector<int> a(n);
    for(int i=0;i<n;i++) cin>>a[i];
    sort(a.begin(), a.end());
    // 赢 a[i]-a[j] 的概率
    unordered_map<int, double> p;
    for(int i=0;i<n;i++)
        for(int j=0;j<i;j++)
            p[a[i]-a[j]] += 2.0/(n*(n-1));
    // 后手前两把总和的概率
    unordered_map<int, double> q;
    for(auto i : p)
        for(auto j : p)
            q[i.first+j.first] += i.second*j.second;
    double ans = 0;
    for(auto i : p)
        for(auto j : q)
            if(i.first>j.first) ans += i.second*j.second;   
    cout<<fixed<<setprecision(10)<<ans<<'\n';
}

【例题 2】ABC326E(普通期望 DP)

  • 状态:E(x)E(x) 为当前值为 xx 时后续期望工资。

  • 初值:E(n)=0E(n)=0。因为此时无法掷出满足 x<yx<yyy

  • 目标:E(0)E(0)

  • 转移:$\displaystyle E(x)=\sum_{y=x+1}^{n}\frac{1}{n}\big(A_y+E(y)\big)$。

    E(x)E(x) 需要从 nn00 进行计算,计算过程中对Ay+E(y) A_y+E(y) 动态维护一个后缀和即可 O(n)O(n)解决。

#include <bits/stdc++.h>
#include <atcoder/modint>
using namespace std;
int main(){
    cin.tie(nullptr)->sync_with_stdio(false);
    cin.exceptions(cin.failbit);
    using mint = atcoder::modint998244353;
    int n; cin>>n;
    vector<int> a(n+1);
    for(int i=1;i<=n;i++) cin>>a[i];
    vector<mint> E(n+1);
    mint suf = 0;
    for(int i=n;i>=0;i--){
        E[i] = suf;
        suf += (a[i]+E[i])/n;
    }
    cout<<E[0].val()<<'\n';
}

【例题 3】ABC360E(期望 DP 线性递推)

状态设计

  • E(x)E(x) 代表当进行了 xx 次交换后,黑球位置的期望值。

初始状态

  • E(0)=1E(0)=1

所求结果

  • E(k)E(k)

转移方程

[1,N][1,N] 独立均匀地随机选择两个整数,总方案数 N2N^2。设黑球当前位置为 pp,选择到的两个整数为 i,ji,j

  • 其中 ipjpi\ne p且 j\ne p 的方案数为 (N1)2(N-1)^2
    i=pj=pi =p且 j=p 的方案数为 11
    这两种情况都不会对黑球的位置产生影响 ,即:

    $$\frac{(N-1)^2+1}{N^2}\,E(x-1)\ \longrightarrow\ E(x). $$
  • 而对于剩余的N2((N1)2+1)=2N2N^2-\big((N-1)^2+1\big)=2N-2种情况 ,黑球位置会被等概率交换到[1,N][1,N] 中除 E(x1)E(x-1) 以外的其他位置

    因此:

    $$\frac{2N-2}{N^2}\cdot \frac{1}{N}\! \left(\sum_{i=1}^{N - 1} i - E(x-1)\right)\ \longrightarrow\ E(x). $$

将两部分相加并整理,得到

$$E(x) = \frac{(N-1)^2+1}{N^2}\,E(x-1) + \frac{2N-2}{N^2}\cdot \frac{1}{N-1}\! \left(\sum_{i=1}^{N} i - E(x-1)\right). $$

因为 i=1Ni=N(N+1)2\sum_{i=1}^{N} i = \dfrac{N(N+1)}{2},继续化简:

$$\begin{aligned} E(x) &= \frac{(N-1)^2+1}{N^2}\,E(x-1) + \frac{2N - 2}{N^2}.\frac 1 {N - 1}\!\left(\sum_{i = 1} ^ N i - E(x-1)\right) \\ &= \frac{(N-2) \,E(x-1) + N + 1}{N} \end{aligned} $$

最终递推式:

E(x)=(N2)E(x1)+N+1N\boxed{\,E(x)=\dfrac{(N-2)E(x-1)+N+1}{N}\,}
#include <bits/stdc++.h>
#include <atcoder/modint>
using namespace std;
int main(){
    cin.tie(nullptr)->sync_with_stdio(false);
    cin.exceptions(cin.failbit);
    using mint = atcoder::modint998244353;
    int n, k; cin>>n>>k;
    vector<mint> E(k+1);
    E[0] = 1;
    for(int i=1;i<=k;i++) E[i] = ((n-2)*E[i-1]+n+1)/n;
    cout<<E[k].val()<<'\n';
}

【例题 4】ABC382E(概率 DP + 期望 DP + 移项消后效性)

概率部分:先求每个卡包爆出 0,1,2,,n0,1,2,\dots,n 张稀有卡的概率(简单概率 DP)

  • 状态设计Pi,jP_{i,j} 表示拆到第 ii 张卡片,累计爆出 jj 张稀有卡的概率。
  • 初始状态P0,0=1\displaystyle P_{0,0}=1
  • 状态转移:$\displaystyle P_{i,j}=p_i\,P_{i-1,j-1} + (1-p_i)\,P_{i-1,j}$
  • 所求结果Pn,\displaystyle P_{n,*}(第 nn 张拆完后的各个 jj 的概率分布)

然后处理问题所要求的期望部分,枚举每拆一个卡包获取到稀有卡的数量,简单期望 DP 处理:


期望部分:每拆一个卡包获得稀有卡的数量(简单期望 DP)

  • 状态设计Ei\displaystyle E_i 表示从 ii 张卡片开始拆包,直到至少有 xx 张卡片的期望步数。

  • 初始状态Ex=0\displaystyle E_x = 0

  • 原始转移式

    $$E_i=\sum_{j=0}^{n} P_{n,j}\,\big(E_{\min(x,i+j)}+1\big) $$

注意:当 j=0j=0 时出现自依赖项,可移项消环。

  • 移项后的等价式

    $$\begin{aligned} E_i &= \sum_{j=1}^{n} P_{n,j}\,\big(E_{\min(x,i+j)}+1\big) + P_{n,0}\,(E_i+1) \\ (1-P_{n,0})\,E_i &= \sum_{j=1}^{n} P_{n,j}\,\big(E_{\min(x,i+j)}+1\big) + P_{n,0} \\ E_i &= \frac{\displaystyle \sum_{j=1}^{n} P_{n,j}\,\big(E_{\min(x,i+j)}+1\big) + P_{n,0}} {1-P_{n,0}} \; . \end{aligned} $$
  • 所求结果E0\displaystyle E_0

#include <bits/stdc++.h>
using namespace std;
int main()
{
    cin.tie(nullptr)->sync_with_stdio(false);
    cin.exceptions(cin.failbit);
    int n,x;
    cin>>n>>x;
    vector<int> a(n);
    for(int i=0;i<n;i++) cin>>a[i];
    vector<double> p(n);
    for(int i=0;i<n;i++) p[i] = a[i]/100.0;
    vector<vector<double>> P(n+1, vector<double>(n+1));
    P[0][0] = 1;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<=n;j++)
        {
            if(j!=n) P[i+1][j+1] += P[i][j]*p[i];
            P[i+1][j] += P[i][j]*(1-p[i]);
        }
    }
    vector<double> E(x+1);
    for(int i=x-1;i>=0;i--)
    {
        E[i] += P[n][0];
        for(int j=1;j<=n;j++) E[i] += P[n][j]*(E[min(x, i+j)]+1);
        E[i] /= (1-P[n][0]);
    }
    cout<<fixed<<setprecision(10)<<E[0]<<'\n';
}

【例题 5】ABC411E E[max]E[\max](分布函数转化)

目标与记号

  • P{X=x}P\{X=x\} 表示所有骰子掷出后最大值xx 的概率,则答案:

    ii×P{X=i}.\sum_{i} i \times P\{X=i\}.

    其中 ii 枚举所有可能出现的点数。

思路

考虑如何求 P{X=x}P\{X=x\} 时,显然所有点数 >x>x 值都不能出现,这很好解决。其次还需要剩下的点数中至少有一个点数为 xx,解决这个限制比较困难。

考虑使用分布函数进行转化。设分布函数为:

F(x)=P{Xx}.F(x)=P\{X\le x\}.

由分布函数性质:

P{aXb}=F(b)F(a1).P\{a\le X\le b\}=F(b)-F(a-1).

因而

P{X=x}=F(x)F(x1).P\{X=x\}=F(x)-F(x-1).

计算 F(x)F(x)

注意到求 F(x)=P{Xx}F(x)=P\{X≤x\} 与求 P{X=x}P\{X=x\} 的差别,相当于把“剩下的点数中至少有一个点数为 xx”这个限制去除,这样问题就非常容易解决了。

我们维护一下每个骰子的点数 x≤x 的面的数量(记为 cic_i),则有:

F(x)=i=1nci6.F(x)=\prod_{i=1}^{n}\frac{c_i}{6}.

将所有骰子的点数进行从大到小的排序,计算完一个点数后就更新一下所有包含这个点数的骰子的 cic_i,并且同步更新上式的值即可。

#include <bits/stdc++.h>
#include <atcoder/modint>
using namespace std;
using ll = long long;
int main()
{
    cin.tie(nullptr)->sync_with_stdio(false);
    cin.exceptions(cin.failbit);
    using mint = atcoder::modint998244353;
    int n;
    cin>>n;
    vector<array<int, 6>> a(n);
    for(int i=0;i<n;i++)
        for(int j=0;j<6;j++)
            cin>>a[i][j];
    map<int, vector<int>> pos;
    for(int i=0;i<n;i++)
        for(int j=0;j<6;j++)
            pos[a[i][j]].push_back(i);
    vector<pair<int, vector<int>>> v(pos.rbegin(), pos.rend());
    mint prod = 1;
    vector<int> cnt(n, 6);
    map<int, mint> f;
    for(auto& [x, w] : v)
    {
        f[x] = prod;
        for(auto i : w)
        {
            prod /= mint(cnt[i])/6;
            cnt[i]--;
            prod *= mint(cnt[i])/6;
        }
    }
    reverse(v.begin(), v.end());
    mint ans = 0;
    for(size_t i=0;i<v.size();i++)
    {
        if(i==0) ans += v[i].first*f[v[i].first];
        else ans += v[i].first*(f[v[i].first]-f[v[i-1].first]);
    }
    cout<<ans.val()<<'\n';
}

【例题 6】ABC412F Socks 4(观察性质消后效性)

S=i=1NAi.S=\sum_{i=1}^N A_i .

期望题目首先考虑期望 DP。注意到题目中仅有“高桥手中的袜子的颜色”这一个变量,因此可简单设计状态:
E(x)E(x) 表示当高桥手中拥有颜色为 xx 的袜子时,还需要的期望抽取次数

考虑如何进行状态转移:当高桥手中拥有颜色为 xx 的袜子时,他从抽屉柜中随机取出一只袜子,耗费一次抽取次数。接下来可能的情况有:

  • 取出颜色为 xx的袜子,此时操作终止,后续期望抽取次数为 00
  • 取出颜色不为 xx的袜子(设颜色为 yy),此操作的概率为 AyS\frac {A_y}S。接下来他会选择能使未来期望抽袜次数最小化的那只袜子放回,后续期望抽取次数为min(E(x),E(y)) \min⁡(E(x),E(y))

因此可得状态转移方程:

$$E(x)=1+\sum_{y\ne x}\frac{A_y}{S}\min\!\big(E(x),E(y)\big). $$

这是一个自依赖且自依赖包括在 min\min 中的状态转移方程,乍一看似乎无法直接求解,然而我们可以感性理解一下:AiA_i越大,越容易一抽即中,因此 E(i)E(i)越小。故状态转移方程即可化为:

$$E(x)=1+\sum_{\substack{y\ne x\\ A_y\le A_x}}\frac{A_y}{S}E(x) +\sum_{\substack{y\ne x\\ A_y>A_x}}\frac{A_y}{S}E(y). $$

移项可得

$$\boxed{\,E(x)= \frac{ S+\displaystyle\sum_{\substack{y \neq x\\ A_y>A_x}} A_y E(y) } { S-\displaystyle\sum_{\substack{y \neq x\\ A_y\le A_x}} A_y }\, }. $$

AiA_i 排序(设按 AA 递增把颜色重新编号为 1,2,,N1,2,\dots,N ),则上式化为前后缀可维护的形式:

$$\,E(x)=\dfrac{S+\sum_{yx} A_y}\, $$

实现要点

  • 先按 AA 升序排序;

  • 维护 y<xAyE(y)\sum_{y<x}A_yE(y)前缀y>xAy\sum_{y>x}A_y后缀,从大到小(或小到大)依次求解 E(x)E(x)

  • 目标为所给颜色 ccE(c)E(c)

#include <bits/stdc++.h>
#include <atcoder/modint>
using namespace std;
using ll = long long;
int main()
{
    cin.tie(nullptr)->sync_with_stdio(false);
    cin.exceptions(cin.failbit);
    using mint = atcoder::modint998244353;
    int n, c;
    cin>>n>>c;
    vector<int> a(n+1);
    for(int i=1;i<=n;i++) cin>>a[i];
    mint sum = accumulate(a.begin()+1, a.end(), mint(0));
    a[c]++;
    vector<int> o(n+1);
    iota(o.begin()+1, o.end(), 1);
    sort(o.begin()+1, o.end(), [&](int i, int j) { return a[i]<a[j]; });
    vector<mint> E(n+1);
    mint pre=0, suf=0;
    for(int i=1;i<=n;i++) pre += a[o[i]];
    for(int i=n;i>=1;i--)
    {
        pre -= a[o[i]];
        E[i] = (sum+suf)/(sum-pre);
        suf += a[o[i]]*E[i];
        if(o[i]==c)
        {
            cout<<E[i].val()<<'\n';
            break;
        }
    }
}


随机游走模型

线性随机游走(U575231 跃迁)

状态设计
E(i)E(i):从位置 ii 跃迁到 i+1i+1一步期望时长。

初始状态
E(1)=1E(1)=1

所求
i=1n1E(i)\displaystyle \sum_{i=1}^{n-1} E(i)

转移方程

E(i)=(1+E(i1)+E(i))+12E(i)=\frac{(1+E(i-1)+E(i))+1}{2}

(分子前半是先回到 i1i-1 再到 ii 进而到 i+1i+1;后半是直接到 i+1i+1。)

移项消后效性

12E(i)=1+12E(i1)  E(i)=2+E(i1).\frac12 E(i)=1+\frac12 E(i-1)\;\\E(i)=2+E(i-1).

树上随机游走

给定一棵有根树,树的某个结点上有一个硬币,在某一时刻硬币会等概率地移动到邻接结点上,问硬币移动到邻接结点上的期望距离。

需要用到的定义

  • T=(V,E)T=(V,E)

  • d(u)d(u)

  • 边权 w(u,v)w(u,v)

  • 父结点 pup_u、根 root\texttt{root}

  • 子集 sonu\texttt{son}_u、兄弟集 siblingu\texttt{sibling}_u

一、向父结点走的期望距离

f(u)f(u) 为从 uu 走到其父 pup_u 的期望距离(f(root)f(\texttt{root}) 不存在),则有。

$$f(u)=\frac{\,w(u,p_u)+\displaystyle\sum_{v\in \texttt{son}_u}\bigl(w(u,v)+f(v)+f(u)\bigr)}{d(u)} $$

分子前半表示直接走向父结点,后半表示先走到子结点、从子结点回到 uu,再到父结点
分母 d(u)d(u) 表示从 uu 以等概率走向任一邻接点。

化简如下

$$\begin{aligned} f(u) &=\frac{\,w(u,p_u)+\displaystyle\sum_{v\in\texttt{son}_u}\bigl(w(u,v)+f(v)+f(u)\bigr)}{d(u)}\\[4pt] &=\frac{w(u,p_u)+\displaystyle\sum_{v\in\texttt{son}_u}\bigl(w(u,v)+f(v)\bigr)+(d(u)-1)f(u)}{d(u)}\\[4pt] &=\,w(u,p_u)+\sum_{v\in\texttt{son}_u}\bigl(w(u,v)+f(v)\bigr)\\[4pt] &=\sum_{(u,t)\in E} w(u,t)\;+\!\!\sum_{v\in\texttt{son}_u} f(v). \end{aligned} $$
  • 对于叶子结点 llf(l)=w(pl,l)\displaystyle f(l)=w(p_l,l)

  • 当树上所有边的边权都为1时,上式可化为:

$$\boxed{\,f(u)=d(u)+\!\!\sum_{v\in\texttt{son}_u} f(v)\,} $$

uu子树的所有结点的度数和,也即 uu子树大小的两倍 1−1(每个结点连向其父亲的边都有且只有一条,除 uupup_u 之间的边只有 11 点度数的贡献外,每条边会产生 22 点度数的贡献)。


向子结点走的期望距离

g(u)g(u) 为从 pup_u 到其子结点 uu 的期望距离。

$$g(u)=\frac{\,w(p_u,u)+\bigl(w(p_u,p_{p_u})+g(p_u)+g(u)\bigr)+ \displaystyle\sum_{s\in\texttt{sibling}_u}\bigl(w(p_u,s)+f(s)+g(u)\bigr)}{d(p_u)}. $$

分子中的第一部分代表直接走向了子结点 uu,第二部分代表先走向了父结点再由父结点走回来然后再向 uu结点走,第三部分代表先走向 uu 结点的兄弟结点再由其走回来然后再向 uu结点走;分母 d(pu)d(p_u)代表从 pup_u 结点走向其任何邻接点的概率相同。

化简如下

$$\begin{aligned} g(u) &= \frac{ w(p_u,u) + \bigl(w(p_u,p_{p_u})+g(p_u)+g(u)\bigr) + \sum_{s\in \mathrm{sibling}_u} \bigl(w(p_u,s)+f(s)+g(u)\bigr)}{d(p_u)} \\[2pt] &= \frac{ w(p_u,u) + w(p_u,p_{p_u}) + g(p_u) + \sum_{s\in \mathrm{sibling}_u} \bigl(w(p_u,s)+f(s)\bigr) + (d(p_u)-1)g(u)}{d(p_u)} \\[2pt] &= w(p_u,u) + w(p_u,p_{p_u}) + g(p_u) + \sum_{s\in \mathrm{sibling}_u} \bigl(w(p_u,s)+f(s)\bigr) \\[2pt] &= \sum_{(p_u,t)\in E} w(p_u,t) + g(p_u) + \sum_{s\in \mathrm{sibling}_u} f(s) \\[2pt] &= \sum_{(p_u,t)\in E} w(p_u,t) + g(p_u) + \bigl(f(p_u) - \sum_{(p_u,t)\in E} w(p_u,t) - f(u)\bigr) \\[2pt] &= g(p_u) + f(p_u) - f(u). \end{aligned} $$

初始状态为 g(root)=0g(root)=0

参考实现(无权树)

vector<int> G[MAXN];

void dfs1(int u, int p) {
  f[u] = G[u].size();
  for (auto v : G[u]) {
    if (v == p) continue;
    dfs1(v, u);
    f[u] += f[v];
  }
}

void dfs2(int u, int p) {
  if (u != root) g[u] = g[p] + f[p] - f[u];
  for (auto v : G[u]) {
    if (v == p) continue;
    dfs2(v, u);
  }
}


【题目清单】

概率论

  • P8804 [蓝桥杯 2022 国 B] 故障(贝叶斯公式)
  • P6154 游走(DAG DP)
  • CF626D Jerry's Protest
  • ABC380G
  • P2221 [HAOI2012] 高速公路(线段树维护期望)

概率 DP

  • CF148D Bag of mice
  • CF167B Wizards and Huge Prize(背包+概率 DP)
  • ABC382E Expansion Packs(概率 DP + 期望 DP + 移项消后效性)
  • P4284 [SHOI2014] 概率充电器(树上概率 DP)
  • P12292 [蓝桥杯 2024 国 Java A] 斗蛐蛐(有后效性)
  • P12293 [蓝桥杯 2024 国 Java A] 合并小球

期望 DP

  • CF1925D Good Trip
  • ABC326E Revenge of "The Salary of AtCoder Inc."
  • ABC360E Random Swaps of Balls
  • ABC402E Payment Required(推荐,背包+状压+期望 DP)
  • ABC411E E [max](分布函数)
  • ABC412F Socks 4(观察性质消后效性)
  • P1850 [NOIP 2016 提高组] 换教室
  • P2473 [SCOI2008] 奖励关(状压+期望 DP)
  • P4206 [NOI2005] 聪聪与可可
  • P2081 [NOI2012] 迷失游乐园(树上期望 DP)
  • P3239 [HNOI2015] 亚瑟王

随机游走

  • U575231 跃迁(线性随机游走)
  • CF1823F Random Walk(树上随机游走)
  • CF2040E Control of Randomness(树上随机游走)
  • P3211 [HNOI2011] XOR和路径(高斯消元)
  • P3232 [HNOI2013] 游走(高斯消元)
  • P6899 [ICPC 2014 WF] Pachinko(高斯消元)

一些 XCPC 的题目

XCPC 经常出概率与期望 DP(由于 Codeforces 的限制,Gym 的题目需要复制链接粘贴到地址栏打开):

评论

0 条
还没有评论。