1 条题解

  • 0
    @ 2025-8-24 22:50:33

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar lzyqwq
    我永远喜欢数据结构。

    搬运于2025-08-24 22:50:33,当前版本为作者最后更新于2023-12-01 16:25:00,作者可能在搬运后再次修改,您可在原文处查看最新版

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

    以下是正文


    CNBLOGS

    我永远喜欢数据结构。

    题目传送门

    • 给出一棵树,初始只有一个点 11,其颜色为 CC

    • qq 次操作,分为两种类型:

      • 0 x c d0\space x\space c\space d,记当前树中一共有 nn 个点,新增一个 n+1n+1,其父亲为 xx,颜色为 cc,两点间边权为 dd

      • 1 x c1\space x\space c,将点 xx 的颜色修改为 cc

    • 每次操作结束后,找到两个颜色不同的点,使得它们的树上距离最大。

    • 多测,q5×105\sum q\le5\times 10^5

    • 6.00 s / 512.00 MB\text{6.00 s / 512.00 MB}

    本文中,点对 (u,v)(u,v) 可以满足 u=vu=v。记 Q=qQ=\sum q

    可以先离线把树建出来,树上距离不变,因为两点间的唯一路径不变。

    首先有个结论:

    有两个点集 S1,S2S_1,S_2,其中 S1S_1 中距离最大的两个点为 u1,v1u_1,v_1S2S_2 中两个距离最大的点为 u2,v2u_2,v_2,则 S1S2S_1\bigcup S_2 中两个距离最大的点 x1,x2{u1,u2,v1,v2}x_1,x_2\in\{u_1,u_2,v_1,v_2\};在 S1,S2S_1,S_2 中各选一个点,使得树上距离最大的点 y1,y2{u1,u2,v1,v2}y_1,y_2\in\{u_1,u_2,v_1,v_2\}

    前者就是在后者的基础上考虑选取的两个点在同一个集合内。

    因为可以证明调整之后一定不劣。我们考虑使用线段树维护。

    首先对于每一种颜色开一棵动态开点线段树,维护区间 [l,r][l,r] 树上距离最远的点对。可以通过上述结论合并信息。

    其次维护一棵线段树 TT,区间 [l,r][l,r] 内维护两个信息:

    • [l,r][l,r] 颜色中的最远点对。

    • [l,r][l,r] 颜色中不同色的最远点对。

    第一个信息也可以通过结论维护。第二个信息,考虑这个点对是否在同一半区间内,若是则拿左 / 右儿子的信息合并,否则一定是一个点的颜色 mid\le mid,另一个 >mid>mid。这等价于分别在颜色为 [l,mid][l,mid][mid+1,r][mid+1,r] 的点构成的点集中选一个点,使得树上距离最大。可以根据结论拿左 / 右儿子的第一个信息合并。

    对于修改操作,若是加点 uu,则在其对应颜色的动态开点线段树上,将 uu 对应的叶子的信息(点对)修改成 (u,u)(u,u)

    若是改点 uu 的颜色,则在其原本颜色的动态开点线段树上,将 uu 对应的叶子信息修改为 ⌈空⌋,因为这个区间内不存在符合条件的点对。将新颜色对应的叶子的信息修改为 (u,u)(u,u)

    每次对每种颜色的动态开点线段树维护好后,考虑 TT 的信息怎么变。显然只有涉及修改的颜色的叶子(及包含它的区间)发生了变化。

    根据两种信息的定义,该叶子的第一种信息应该变为其对应动态开点线段树根上的信息,即这种颜色的最远点对。第二种信息应该变为 ⌈空⌋,因为显然不存在两个不同色的点。

    还有一个注意点,求解 dis(u,v)\text{dis}(u,v) 的时候我们使用 depu+depv2depLCA(u,v)dep_u+dep_v-2\cdot dep_{\text{LCA}(u,v)}。但是这里一次操作合并信息的次数可以到达 O(logQ)\mathcal{O}(\log Q)。而这题却出乎意料地卡了 O(Qlog2Q)\mathcal{O}(Q\log^2 Q) 的做法。因此我们需要更快速的信息合并方式。

    显然需要更高效地求 LCA\text{LCA}。记 f=LCA(u,v)f=\text{LCA}(u,v)。那么记 edxed_x 为点 xx 子树中 dfndfn 序最大的那个,显然有 dfnfdfnu,dfnvedfdfn_f\le dfn_u,dfn_v\le ed_f

    特判掉 uuvvff 的情况。我们记 valival_idfndfn 序为 ii 的点的父亲的 dfndfn 序。那么 $\boldsymbol{dfn_f=\min\limits_{i=dfn_u}^{dfn_v} val_i}$。此处默认 dfnudfnvdfn_u\le dfn_v

    容易发现对于任意 xxi(dfnx,edx],validfnf\forall \,i\in(dfn_x,ed_x],val_i\ge dfn_f。你考虑 xx 一定能过通过不少于一条边向下走到这个范围内的点。

    根据上面这个结论显然可以得到对于 i[dfnu,dfnv],validfnfi\in[dfn_u,dfn_v],val_i\ge dfn_f。因为 [dfnu,dfnv](dfnf,edf][dfn_u,dfn_v]\subseteq (dfn_f,ed_f]

    其次证明等号可以取到,因为 u,vu,v 一定在 ff 的不同子树内,由于 dfnudfnvdfn_u\le dfn_v,所以 uu 所在子树先遍历,设 vv 所在子树的根为 rtrt,可以得到 dfnudfnrtdfnvdfn_u\le dfn_{rt}\le dfn_v

    你发现 valdfnrt=dfnf\boldsymbol{val_{dfn_{rt}}=dfn_f}

    所以我们可以用 ST 表做这个 RMQ 问题,这样查询是 O(1)\mathcal{O}(1) 的。

    其次就是这题空信息的处理比较麻烦,可能需要较多特判。一种比较通用的方式是,对于信息我再记录一个变量 ee,表示其是否为空。定义 \oplus 为合并运算,若两个信息 a,ba,b 满足 eb=1e_b=1,则 ab=aa\oplus b=a

    事实上好像更麻烦。

    这样一来,时间、空间复杂度均为 O(QlogQ)\mathcal{O}(Q\log Q)

    提交记录 代码

    • 1

    信息

    ID
    9241
    时间
    6000ms
    内存
    512MiB
    难度
    7
    标签
    递交数
    0
    已通过
    0
    上传者