2 条题解

  • 9
    @ 2026-9-22 20:26:33

    Colorful Tree

    题目链接: HDU 2017 Colorful Tree 。

    题目描述:

    有 nn 个点的树,每个点有一个颜色 aia_i ,求所有 (u,v)(u,v) 满足 1≤u<v≤n1\le u<v\le n 的点对的路径上的不同颜色的和。

    n≤2×105,1≤ai≤nn\le 2\times10^5,1\le a_i\le n 。

    考虑对于枚举每一个颜色并计算它带来的贡献。对于枚举的颜色 cc ,我们应该视所有 ai=ca_i=c 的 ii 为关键点,那么这个颜色 cc 的贡献就是所有经过了关键点的路径。

    这个并不好算,我们考虑把它容斥为不经过任意一个关键点的路径。

    此时问题就明了了:将所有的关键点去掉后的连通块的大小的平方和。

    由于有关键点,我们对所有的关键点建立虚树。为了方便强行钦定 00 为根,连边 (0,1)(0,1) ,并设 00 为关键点。

    接下来就我们不妨自下而上考虑:对于一个关键点 uu ,遍历它在原树上的儿子 vv ,并计算 vv 的子树权值和(即去掉 uu 之后的 vv 这一个连通块大小)的平方,然后将 uu 整个子树的权值全部置为 00 。初始时所有节点均置为 11 。

    复杂度容易说明:建立虚树的复杂度 O(nlog⁡n)\mathcal{O}(n\log n) ,之后每一个节点都只会出现在一个虚树中并遍历一次它的儿子,执行一遍线段树操作,于是这部分复杂度 O(nlog⁡n)\mathcal{O}(n\log n) 。总复杂度就是 O(nlog⁡n)\mathcal{O}(n\log n) ,可以通过。

    代码十分简单,不放了。

    PS: 这里虚树的作用其实是为了保证自下而上的遍历,所以也可以不用虚树,改为将所有的关键点按深度排序处理。

    • 0
      @ 2026-9-22 19:03:46

      直接枚举所有路径并统计颜色种类的复杂度是 O(n2)O(n^2),对于 n≤2×105n \le 2 \times 10^5 的数据范围会超时。

      我们需要转换思维,从“每条路径有多少种颜色”转变为“每种颜色对总答案的贡献是多少”。

      假设树上一共有 nn 个节点,那么树上的点对(路径)总数为 n(n−1)2\frac{n(n-1)}{2}。

      对于任意一种颜色 cc,它对答案的贡献就等于包含至少一个颜色 cc 节点的路径数量。

      直接求包含颜色 cc 的路径比较困难,我们可以使用补集思想:包含颜色 cc 的路径数 = 总路径数 - 完全不包含颜色 cc 的路径数。

      如果我们把树上所有颜色为 cc 的节点删除,整棵树会被分割成若干个不相交的连通块(子树)。

      假设某个连通块的大小为 SS,那么完全在这个连通块内部的路径都不会经过颜色为 cc 的节点,这样的路径数量为 S(S−1)2\frac{S(S-1)}{2}。

      因此,颜色 cc 的贡献为:

      $$\text{Contribution}(c) = \frac{n(n-1)}{2} - \sum_{i} \frac{S_i(S_i-1)}{2}$$

      其中 SiS_i 是删除颜色 cc 的节点后,各个连通块的大小。

      可以使用树形 dpdp 计算连通块的大小。

      设 f[c]f[c],表示目前遍历过程中,颜色为 cc 的节点已经分隔的连通块节点总数。

      当我们遍历到一个节点 uu(颜色为 cuc_u),并准备进入它的子树 vv 时:

      • 记录下进入 vv 之前的分隔数:pre=f[cu]pre=f[c_u]。
      • 递归遍历子树 vv。
      • 遍历完 vv 后,子树 vv 的总大小为 siz[v]siz[v]。在子树 vv 内部,有一些节点已经被子树内部的 cuc_u 颜色节点分隔了,分隔的数量就是 f[cu]−pref[c_u]-pre。
      • 那么,子树 vv 中没有被分隔且能一路连通到节点 uu 的节点数量就是 cntv=siz[v]−(f[cu]−pre)cntv=siz[v] - (f[c_u] - pre)。这些节点就构成了一个不包含颜色 cuc_u 的连通块。
      • 我们从总路径中减去这个连通块内部的路径数 cnt⋅(cnt−1)2\frac{\text{cnt}\cdot(\text{cnt}-1)}{2},并将这部分大小累加到 f[cu]f[c_u] 中。

      当整棵树遍历完成后,每种颜色可能在靠近树根的地方还剩下一个“顶部连通块”。对于颜色 cc,这个顶部连通块的大小为 n−f[c]n - f[c],同样需要将其内部路径数减去。

      • @ 2026-9-22 20:28:57

        注解:“截断”的意思是将子树与祖先(包括父亲)分隔开。

    • 1

    信息

    ID
    2750
    时间
    1000ms
    内存
    128MiB
    难度
    6
    标签
    (无)
    递交数
    57
    已通过
    11
    上传者