1 条题解

  • 0
    @ 2025-8-24 22:18:28

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar 梦梦子
    **

    搬运于2025-08-24 22:18:28,当前版本为作者最后更新于2020-03-12 08:47:04,作者可能在搬运后再次修改,您可在原文处查看最新版

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

    以下是正文


    c(x,y)c(x,y)​表示边权。

    T2T_2进行点分治

    x,yx,y在当前点分树中到根的距离为depx,depydep_x,dep_y

    那么我们可以认为(x,y)(x,y)的边权为dist1(x,y)+depx+depydist_1(x,y)+dep_x+dep_y

    因为,若在当前点分树中,lca(x,y)lca(x,y)等与点分树的重心,那么上式是成立的,否则c(x,y)dist1(x,y)+depx+depyc(x,y)\leq dist_1(x,y)+dep_x+dep_y

    真实的c(x,y)c(x,y)会递归进下一个点分树被考虑到,我们可以认为这个式子依然成立,对答案不会有影响

    那么我们希望在当前点分树的意义下删除一些一定不会对最终答案有贡献的(x,y)(x,y)

    考虑以下算法:

    1.首先求出当前点分树中的点,在T1T_1当中的虚树。

    2.对于所有当前点分树中的点xx,建立新点xx',在虚树上加一条(x,x)(x,x')边,边权为depxdep_x,我们称mp[x]=xmp[x']=x,我们称所有这样的xx'为源点

    3.跑两遍树dpdp,对于虚树上每个点yy,记录pre[y]pre[y]表示离yy最近的源点(如果有多个最近的随便记一个即可),dist[y]dist[y]表示pre[y]pre[y]yy的距离

    4.枚举虚树中每一条边(a,b)(a,b),将(mp[pre[a]],mp[pre[b]],dist[a]+dist[b]+l(a,b))(mp[pre[a]],mp[pre[b]],dist[a]+dist[b]+l(a,b))ll表示虚树上一条边的长度。这条边加入候选边集

    所有点分树的所有候选边集大小总共O(nlogn)O(n\log n),对这些边进行kruskalkruskal算法,即可算出答案。

    使用预处理STST表求lcalca可在O(nlogn)O(n\log n)选出候选边集。

    算法正确性证明请读者自行思考。

    算法复杂度O(nlogn+nlognlog(nlogn))O(n\log n+n\log n\log (n\log n))

    后面那第二个log\log只是给nlognn\log n条边排序的复杂度,众所周知sortsort排序是很快的,因此此算法可在一定意义上认为是O(nlogn)O(n\log n)stdstd是基于这种做法,因此很多使用boruvkaboruvka算法或其他做法的O(nlog2n)O(n\log^2n)可能会被卡常,实际上时限非常宽松。

    按照此算法,atcoderatcoder上的那个子问题可做到O(n)O(n)

    • 1

    信息

    ID
    5210
    时间
    4000ms
    内存
    500MiB
    难度
    7
    标签
    递交数
    0
    已通过
    0
    上传者