1 条题解

  • 0
    @ 2025-10-28 16:50:07

    题意理解

    我们有一棵 nn 个节点的树,表示 nn 个城市和连接它们的道路。

    mm 次语言传播工作,第 ii 次传播从 sis_itit_i(走唯一的最短路径,即树上路径),把第 ii 种通用语教给路径上的所有城市。

    定义:两个城市 uuvv 可以开展贸易,当且仅当存在一种通用语 LL,使得 uuvv 的路径上的所有城市都会语言 LL

    换句话说,uvu \to v 的路径必须完全包含在某一次语言传播的路径中。

    我们需要统计有多少个无序对 (u,v)(u, v)u<vu < v)可以开展贸易。


    问题转化

    对于任意两个城市 u,vu, v,设 PuvP_{uv} 表示 uuvv 的路径(按树上的唯一路径)。

    条件:存在某次传播 (si,ti)(s_i, t_i),其路径 QiQ_i 满足 PuvQiP_{uv} \subseteq Q_i


    关键观察

    1. 路径包含关系
      在树上,一条路径 PuvP_{uv} 被另一条路径 QQ 包含,当且仅当 PuvP_{uv} 的两个端点 u,vu, v 都在 QQ 上,并且 PuvP_{uv}QQ 的一段连续部分。
      更准确地说:
      QQ 的端点是 a,ba, bPuvP_{uv} 的端点是 u,vu, v
      PuvQP_{uv} \subseteq Q 当且仅当 $\mathrm{dist}(a, u) + \mathrm{dist}(u, v) + \mathrm{dist}(v, b) = \mathrm{dist}(a, b)$,
      或者 $\mathrm{dist}(a, v) + \mathrm{dist}(v, u) + \mathrm{dist}(u, b) = \mathrm{dist}(a, b)$。
      其实等价于:u,vu, v 都在 QQ 上,且 u,vu, v 之间的路径是 QQ 的一部分。

    2. 等价条件
      在树上,路径 PxyP_{xy} 被路径 PabP_{ab} 包含的充要条件是:

      $$\mathrm{dist}(a, x) + \mathrm{dist}(x, y) + \mathrm{dist}(y, b) = \mathrm{dist}(a, b) $$

      或者

      $$\mathrm{dist}(a, y) + \mathrm{dist}(y, x) + \mathrm{dist}(x, b) = \mathrm{dist}(a, b) $$

      因为 dist(x,y)=dist(y,x)\mathrm{dist}(x, y) = \mathrm{dist}(y, x),这两个条件其实是对称的,就是 x,yx, yaba \to b 路径上且顺序是 axyba \to x \to y \to b(或 ayxba \to y \to x \to b)。

    3. 简化判断
      更简单的判断:x,yx, y 在路径 aba \to b 上,当且仅当:

      $$\mathrm{dist}(a, x) + \mathrm{dist}(x, b) = \mathrm{dist}(a, b) \quad\text{且}\quad \mathrm{dist}(a, y) + \mathrm{dist}(y, b) = \mathrm{dist}(a, b) $$

      并且 x,yx, y 之间的路径完全落在 aba \to b 上(自动满足,因为树上两点唯一路径)。

      所以只需检查 xxyy 是否都在路径 aba \to b 上。


    暴力做法(小数据)

    对于 n,m300n, m \le 300,我们可以:

    • 预处理任意两点距离 dist(u,v)\mathrm{dist}(u, v)(BFS nn 次,O(n2)O(n^2))。
    • 对每对 (u,v)(u, v)u<vu < v),检查是否存在一次传播 (si,ti)(s_i, t_i) 使得 uuvv 都在路径 sitis_i \to t_i 上。

    判断 uu 在路径 sitis_i \to t_i 上的方法:

    $$\mathrm{dist}(s_i, u) + \mathrm{dist}(u, t_i) = \mathrm{dist}(s_i, t_i) $$

    复杂度:O(n2m)O(n^2 m),对于 n,m300n, m \le 300 可过。


    优化思路

    我们需要数有多少点对 (u,v)(u, v) 满足:存在 ii 使得 u,vu, v 都在路径 sitis_i \to t_i 上。

    等价于:点对 (u,v)(u, v) 如果被某条传播路径同时经过,则贡献 1。


    转化为:对每个语言路径,数它包含的点对数量

    对于一条语言路径 PP(长度为 L+1L+1 个节点),它包含的点对数量是 (L+12)\binom{L+1}{2}

    但是不同语言路径可能包含相同的点对,直接相加会重复计数。

    所以问题变成:给定 mm 条树上路径,求它们的点并集的点对数量。
    即:令 SiS_i = 路径 ii 上的点集,求 i=1m(Si2)|\bigcup_{i=1}^m \binom{S_i}{2}|,其中 (Si2)\binom{S_i}{2} 表示 SiS_i 中所有点对。


    容斥原理

    AijA_{ij} 表示事件“点对 (i,j)(i, j) 被某条路径包含”。

    我们要求:

    $$\sum_{1 \le i < j \le n} [\exists k: (i,j) \in \mathrm{Path}(s_k, t_k)] $$

    这等于:

    $$\sum_{1 \le i < j \le n} \left[ \bigvee_{k=1}^m (i,j \in P_k) \right] $$

    其中 PkP_k 是第 kk 条路径的点集。


    另一种思路:对每个点对,判断是否被至少一条路径包含

    判断点对 (u,v)(u, v) 是否被某条路径 PP 包含:
    路径 PP 包含 (u,v)(u, v) 当且仅当 PP 包含 uuvv,且 u,vu, vPP 上连续(自动满足)。

    所以只需判断 u,vu, v 是否同时在某条路径上。


    高效算法(n,m105n, m \le 10^5

    我们可以用 树上差分 + LCA 来标记每条路径覆盖的边或点,但这里需要知道点对是否被同一条路径覆盖。

    一个技巧:
    对每个点 xx,记录包含 xx 的路径集合(用 bitset 或哈希),然后判断 u,vu, v 是否有公共路径?
    mm 很大时不行。


    正解思路(参考)

    事实上,已知一个方法:

    1. 对每个语言路径,把它覆盖的标记(用该语言的编号)。
    2. 点对 (u,v)(u, v) 可行当且仅当 uvu \to v 路径上的所有边都被至少同一种语言覆盖。

    因为如果 uvu \to v 路径上所有边都被某条语言路径覆盖,那么整条路径就被它包含。

    问题转化为:给 mm 条路径,标记边,问有多少点对之间的路径上的边都被至少一个共同语言覆盖。


    进一步转化

    对边考虑:每条边可能被若干种语言覆盖。
    点对 (u,v)(u, v) 可行当且仅当 uvu \to v 路径上的所有边有一个公共的语言(不一定同一条路径,而是同一种语言编号)。

    因为一种语言对应一条路径,如果 uvu \to v 路径上的边都被语言 LL 覆盖,那么 uvu \to v 路径一定完全在语言 LL 的路径内部。


    具体算法

    1. 对每种语言 ii,它覆盖的边是 sitis_i \to t_i 路径上的边。
    2. 对每条边 ee,记录覆盖它的语言集合 LeL_e
    3. 我们要求点对 (u,v)(u, v) 满足:ePuvLe\bigcap_{e \in P_{uv}} L_e \neq \varnothing

    也就是说,uvu \to v 路径上所有边的覆盖语言集合交集非空。


    实现方法

    • 对每种语言,路径 sitis_i \to t_i 上的边加入语言 ii(用树上差分,给边打标记)。
    • 然后问题变成:有多少点对,路径上的所有边都包含某种共同语言 xx

    换个角度:对每种语言 xx,考虑所有被它覆盖的边,这些边形成一条路径(就是 sxtxs_x \to t_x 路径)。
    那么所有点对 (u,v)(u, v) 如果完全在这条路径上,就满足条件。

    所以又回到:点对 (u,v)(u, v) 满足它在某条语言路径上。


    最终算法

    我们只需对每条语言路径 PP,计算它上面的点对数量 (P2)\binom{|P|}{2},然后去重。

    去重:如果两条语言路径有重叠的点对,只算一次。

    这相当于求 mm 条路径的点集的并集,然后计算这个并集中有多少点对。


    去重方法

    点对 (u,v)(u, v) 可能出现在多条路径中,我们只计一次。

    我们可以用 二维平面 扫描的方法,但较复杂。
    一个简单方法:
    对每个点对,它第一次被哪条路径覆盖?很难。

    但已知一个 O(n+m)O(n + m) 做法(cf. 类似题目):
    把路径按某种顺序处理,用并查集维护已经覆盖的连续段。


    简单总结

    对于本题 n,m105n, m \le 10^5,标算可能是:

    1. 求出每条路径的节点集合(用 O(1) LCA 可得路径长度)。
    2. 用容斥或线段树合并维护覆盖点对去重。

    但实现较复杂,这里不展开代码。


    公式总结

    • 两点距离:$\mathrm{dist}(u, v) = \mathrm{depth}[u] + \mathrm{depth}[v] - 2 \times \mathrm{depth}[\mathrm{LCA}(u, v)]$
    • xx 在路径 aba \to b 上:
    $$\mathrm{dist}(a, x) + \mathrm{dist}(x, b) = \mathrm{dist}(a, b) $$
    • 路径包含点对:路径 PP 包含点对 (u,v)(u, v) 当且仅当 u,vPu, v \in P
    • 1

    信息

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