1 条题解

  • 0
    @ 2025-8-24 22:17:36

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar RyexAwl
    人生有梦,各自精彩

    搬运于2025-08-24 22:17:36,当前版本为作者最后更新于2022-02-21 13:18:08,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    首先,定义“点 tt 对点 uu 有贡献”等价于 ttuu 的独特的城市。

    钦定点 uu 为根,令点集 LuL_u 表示到所有到点 uu 距离最远的叶子节点构成的集合,对点 uu 有贡献的点一定在 LuL_u 中所有点到 uu 的路径的交上。

    注意,路径交上的所有点并不都一定对 uu 有贡献。

    因此一个想法就是考虑找到随便一个点 vv 距离点 uu 最远,考察 u,vu,v 两点间的路径上的点。

    而考虑离点 uu 最远的点,可以选一条直径 sts-ts,ts,t 两个点中一定存在一个点是距离点 uu 最远的点。

    进而问题就转化成了:给定一个点 rtrt,以 rtrt 为根,求出每个点 uurtrt 路径上所有对点 uu 有贡献的点的颜色数。

    分别以 s,ts,trtrt 求一遍上面的问题即可。

    接下来考虑如何去求解上面转化后的问题。

    考虑一个在点 uu 到根节点路径上的点 pp 不会对点 uu 产生贡献的充分必要条件:存在一个点 tt 使得 ttuu 的距离等于 ppuu 的距离,按照点 tt 的位置分类讨论:

    • ttuu 子树内。

    • ttuu 子树外。

    考虑维护出一个点集 TuT_uxTu\forall x\in T_u 满足:

    • xx 在根节点到 fa[u]fa[u] 的路径上。

    • 不存在一个点 ttuu 的子树外,使得 dist(u,t)=dist(u,x)dist(u,t)=dist(u,x)

    同时考虑点集 SuS_uxSu\forall x\in S_u 满足:

    • xx 在根节点到 uu 的路径上。

    • 不存在一个点 tt ,使得 dist(u,t)=dist(u,x)dist(u,t)=dist(u,x)

    并且 SuTuS_u\subseteq T_u,删掉 TuT_u 中所有满足存在一个点 ttuu 子树内,使得 dist(u,x)=dist(u,t)dist(u,x)=dist(u,t) 的点 xx 即可将 TuT_u “变成” SuS_u

    考虑 uu 的一个儿子 vv,想要构造出 TvT_v,需要对 TuT_u 进行哪些 “改造”(或者说点集如何变化)。

    vv 的子树外等价于 fa[v]fa[v] 的子树外并上 vv 的兄弟子树

    • 先令 TvTu{u}T_v\gets T_u\cup \{u\}

    • 删掉 TvT_v 中所有满足存在一个点 tt 满足 tt 属于 vv 的兄弟的子树中,dist(u,t)=dist(u,x)dist(u,t) = dist(u,x) 的点 xx

    而 “删掉 TvT_v 中所有满足存在一个点 tt 满足 tt 属于 vv 的兄弟的子树中,dist(u,t)=dist(u,x)dist(u,t) = dist(u,x) 的点 xx”,可以转化成 “删掉 TvT_v 中所有 dist(u,x)<=v 的所有兄弟子树的最大深度 + 1dist(u,x) <= \text{v 的所有兄弟子树的最大深度 + 1} 的点 xx

    考虑对该树做长链剖分,令点 uu 的长儿子为 son[u]son[u]maxdist(u)\mathrm{maxdist(u)} 表示 uu 子树内距离 uu 距离最远的点与 uu 的距离,ts[u]ts[u] 表示 uu 的次长儿子,len(u)=maxdist(ts[u])+1\mathrm{len(u)}=\mathrm{maxdist(ts[u])}+1

    注意到,对于 uu 的所有非长儿子,在点集 Tu{u}T_u\cup\{u\} 中要删除的点集都一样。

    而对于点 uu 的长儿子,要删除的点集为 Tu{u}T_u\cup\{u\} 中所有满足 dist(u,x)len(u)dist(u,x)\le \mathrm{len(u)} 的点 xx

    考虑在 DFS 的过程中维护点集 TuT_u,在进入子树 uu 前,全局维护的信息应为 TuT_u 的信息。

    进入子树 uu 后依次进行以下操作:

    • 删除当前全局维护的点集中所有满足 dist(u,x)len(u)dist(u,x)\le \mathrm{len(u)} 的点 xx

    • 在当前全局维护的点集中加入点 uu

    • 递归长子树。

    • 删掉当前全局维护的点集中所有满足 dist(u,x)maxdist(u)dist(u,x)\le \mathrm{maxdist(u)},当前全局维护的点集为 SuS_u,同时也是对于任意轻儿子 vvTvT_v

    • 依次递归轻子树,其中在递归轻子树前需要将点 uu 加入全局维护的点集中。

    • 如果点 uu 在全局维护的点集中,删除点 uu

    这样操作的合法性:

    在递归长子树时,在长子树内进行的 “删除操作”影响到的 uu 的祖先,至多影响到 uumaxdist(u)2\mathrm{maxdist(u)}-2 级祖先,而这些点在处理轻子树之前本来就需要被删除。

    而在递归非长子树 vv 时,只会至多影响 uumaxdist(v)1\mathrm{maxdist(v)}-1 级祖先,而这些祖先一定都被删光光了,因此在处理轻子树时一定不会影响到集合中 uu 的祖先。

    这样,一个元素至多贡献儿子个数次总复杂的为 O(n)O(n)

    • 1

    [JOI 2019 Final] 独特的城市 / Unique Cities

    信息

    ID
    5134
    时间
    2000ms
    内存
    250MiB
    难度
    6
    标签
    递交数
    0
    已通过
    0
    上传者