1 条题解

  • 0
    @ 2026-5-18 21:31:23

    E. LeaFall 详细题解

    一、问题理解

    有一棵 nn 个节点的树。每个节点 ii 以概率 pri=piqipr_i = \frac{p_i}{q_i} 独立倒下(移除自身和邻边),剩余节点形成森林。需要计算期望的叶子对数量(无序,叶子定义为度数为 11 的节点),结果对 998244353998244353 取模。


    二、核心公式

    设随机变量 XX = 叶子对数量。由期望线性性:

    $$E[X] = \sum_{1 \le u < v \le n} P(\text{节点 } u \text{ 和 } v \text{ 都是叶子}) $$

    标程的核心思想:

    1. 先假设所有顶点对独立,计算近似期望
    2. 再对距离 2\le 2 的顶点对进行修正(因为只有这些顶点的事件会相互依赖)

    三、符号定义

    • pri=piqipr_i = \frac{p_i}{q_i} 表示节点 ii 倒下的概率
    • qri=1priqr_i = 1 - pr_i 表示节点 ii 未倒下的概率
    • fall[i]=prifall[i] = pr_i
    • stay[i]=1pristay[i] = 1 - pr_i

    四、单个节点成为叶子的概率 p2[i]p2[i]

    节点 ii 成为叶子,当且仅当:

    • ii 未倒下
    • ii 的邻居中恰好有一个未倒下,其余全部倒下

    N(i)N(i)ii 的邻居集合。

    先计算 p1[i]p1[i]ii 未倒下且所有邻居都倒下的概率:

    p1[i]=stay[i]uN(i)prup1[i] = stay[i] \cdot \prod_{u \in N(i)} pr_u

    然后,ii 成为叶子的概率 = 对每个邻居 uu,让 uu 成为那个唯一未倒下的邻居:

    $$p2[i] = \sum_{u \in N(i)} \left( stay[i] \cdot (1-pr_u) \cdot \prod_{\substack{w \in N(i) \\ w \ne u}} pr_w \right) $$

    注意到:

    $$stay[i] \cdot \prod_{\substack{w \in N(i) \\ w \ne u}} pr_w = \frac{p1[i]}{pr_u} $$

    所以:

    $$p2[i] = \sum_{u \in N(i)} \frac{p1[i]}{pr_u} \cdot (1-pr_u) = p1[i] \cdot \sum_{u \in N(i)} \frac{1-pr_u}{pr_u} $$

    标程中的计算正是这个公式:

    p1[i] = sub(1, p[i]);
    for (int u : adj[i]) p1[i] = mul(p1[i], p[u]);
    
    for (int u : adj[i]) {
        int term = mul(p1[i], mul(inv(p[u]), sub(1, p[u])));
        add2(p2[i], term);
    }
    

    五、初始期望(假设独立)

    如果所有顶点对独立,则:

    $$E_{\text{indep}} = \sum_{u<v} p2[u] \cdot p2[v] = \frac{1}{2}\left( \left(\sum p2[i]\right)^2 - \sum p2[i]^2 \right) $$

    标程第一段循环实现了这个:

    int ans = 0, sum = 0;
    for (int i = 1; i <= n; i++) {
        add2(ans, mul(p2[i], sum));
        add2(sum, p2[i]);
    }
    

    这里 ans 累积的是 j<ip2[j]p2[i]\sum_{j< i} p2[j] \cdot p2[i],即 u<vp2[u]p2[v]\sum_{u<v} p2[u] \cdot p2[v]


    六、修正距离为 11 的顶点对(相邻节点)

    对于相邻节点 (u,v)(u,v),事件“uu 是叶子”和“vv 是叶子”不独立,需要重新计算联合概率并替换独立近似。

    联合概率uuvv 都是叶子

    条件:

    • uu 未倒下,vv 未倒下
    • uu 的邻居中恰好一个未倒下(这个未倒下的邻居必须是 vv,否则 uu 会有其他未倒下邻居)
    • vv 的邻居中恰好一个未倒下(这个未倒下的邻居必须是 uu
    • 其他所有邻居(除了 uuvv 彼此)必须全部倒下

    N(u)N(u)uu 的邻居集合,N(v)N(v)vv 的邻居集合。

    则联合概率为:

    $$\begin{aligned} P(\text{leaf}_u \land \text{leaf}_v) &= stay[u] \cdot stay[v] \cdot (1-pr_v) \cdot (1-pr_u) \\ &\quad \cdot \prod_{w \in N(u) \setminus \{v\}} pr_w \cdot \prod_{w \in N(v) \setminus \{u\}} pr_w \end{aligned} $$

    注意 $stay[u] \cdot \prod_{w \in N(u) \setminus \{v\}} pr_w = \frac{p1[u]}{pr_v}$。

    所以:

    $$P(\text{leaf}_u \land \text{leaf}_v) = \frac{p1[u]}{pr_v} \cdot \frac{p1[v]}{pr_u} \cdot (1-pr_u)(1-pr_v) $$

    标程中:

    int pi = mul(p1[i], inv(p[u]));   // = p1[i] / p[u]
    int pu = mul(p1[u], inv(p[i]));   // = p1[u] / p[i]
    add2(ans, mul(pi, pu));           // 加上精确联合概率
    sub2(ans, mul(p2[i], p2[u]));     // 减去之前独立的贡献
    

    七、修正距离为 22 的顶点对(经过中间节点 ii

    uuvvii 的两个不同邻居,即 iiuuvv 的公共邻居。需要计算 P(leafuleafv)P(\text{leaf}_u \land \text{leaf}_v)

    情况分析uuvv 成为叶子的条件涉及 ii 的状态。

    标程将 ii 是否倒下分开处理:

    情况 1:ii 未倒下

    uu 成为叶子的条件:

    • uu 未倒下
    • uu 的邻居中恰好一个未倒下,且这个邻居必须是 ii(因为 ii 未倒下,uu 的其他邻居必须全部倒下)

    所以 uu 成为叶子的概率(给定 ii 未倒下)为:

    p1[u]pri(1pri)\frac{p1[u]}{pr_i} \cdot (1-pr_i)

    因为 p1[u]=stay[u]wN(u)prwp1[u] = stay[u] \cdot \prod_{w \in N(u)} pr_w,除以 pripr_i 去掉 ii 的因子,再乘以 stay[i]=1pristay[i] = 1-pr_i 是因为 ii 未倒下。

    标程中:

    int pu = mul(p1[u], inv(p[i]));   // = p1[u] / p[i]
    add2(ans, mul(sum, pu));
    add2(sum, mul(pu, sub(1, p[i])));
    

    情况 2:ii 倒下

    uu 成为叶子的条件:

    • uu 未倒下
    • uu 的邻居中恰好一个未倒下,且这个邻居不能是 ii(因为 ii 已倒下),所以必须是 uu 的其他某个邻居

    计算 uu 成为叶子且 ii 倒下的概率 = p2[u]P(leafui 未倒下)p2[u] - P(\text{leaf}_u \land i \text{ 未倒下})

    其中 $P(\text{leaf}_u \land i \text{ 未倒下}) = \frac{p1[u]}{pr_i} \cdot (1-pr_i)$。

    标程中:

    int pu = sub(p2[u], mul(p1[u], mul(inv(p[i]), sub(1, p[i]))));
    add2(ans, mul(sum, pu));
    add2(sum, mul(pu, inv(p[i])));
    

    八、算法流程总结

    1. 读入 nn、每个节点的 (pi,qi)(p_i, q_i)、树的边
    2. 计算 pri=piqi1modMpr_i = p_i \cdot q_i^{-1} \bmod M
    3. 计算 p1[i]p1[i]:节点 ii 未倒下且所有邻居倒下的概率
    4. 计算 p2[i]p2[i]:节点 ii 成为叶子的概率
    5. 初始化 ans 为所有无序对的独立贡献 u<vp2[u]p2[v]\sum_{u<v} p2[u] \cdot p2[v]
    6. 对每条边 (u,v)(u,v)(距离 11):
      • 加上精确联合概率
      • 减去独立贡献
    7. 对每个节点 ii,处理以 ii 为中间节点的距离 22 的顶点对:
      • ii 未倒下时的情况
      • ii 倒下时的情况
    8. 输出 ans

    九、复杂度分析

    • 预处理 p1,p2p1, p2O(deg)=O(n)O(\sum deg) = O(n)
    • 初始贡献:O(n)O(n)
    • 距离 11 修正:O(n)O(n)(每条边一次)
    • 距离 22 修正:O(deg2)O(\sum deg^2),最坏情况星形树可能 O(n2)O(n^2),但由于 deg2\sum deg^2 在稀疏图中通常可控,且 n105n \le 10^5 时仍可接受

    十、示例验证

    以题目第二个测试用例为例:

    • n=3n=3,树为 1231-2-3,所有 pri=12pr_i = \frac{1}{2}
    • 计算得 p2[1]=p2[3]=14p2[1]=p2[3]=\frac{1}{4}p2[2]=12p2[2]=\frac{1}{2}
    • 初始独立贡献:$p2[1]p2[2] + p2[1]p2[3] + p2[2]p2[3] = \frac{1}{8} + \frac{1}{16} + \frac{1}{8} = \frac{5}{16}$
    • 修正后得到 38\frac{3}{8},与题目一致

    十一、总结

    要点 说明
    核心思想 线性期望 + 独立近似 + 局部修正
    关键公式 $p2[i] = p1[i] \sum_{u \in N(i)} \frac{1-pr_u}{pr_u}$
    修正范围 只修正距离 2\le 2 的顶点对
    时间复杂度 O(deg2)O(\sum deg^2),实际可过
    模运算 使用模逆处理分数
    • 1

    信息

    ID
    7235
    时间
    1000ms
    内存
    256MiB
    难度
    9
    标签
    递交数
    1
    已通过
    1
    上传者