zoukankan      html  css  js  c++  java
  • 洛谷 P4220 [WC2018]通道

    11328 年, C 国的科学家们研发了一种高速传送通道,可以在很短的时间内把居民从通道的一端送往另一端,这些通道都是双向的。

    美中不足的是,这种传送通道需要进行大量的维护和检修。经过规划, C 国总统决定在 M 城中新建这种通道,在 M 城中,建立了 (n) 个传送站和 (3*(n-1)) 条传送通道,这些传送通道被分为 (3) 组,每一组都包含了 ((n-1)) 条通道。

    当任意一组通道运行时,居民都可以通过这组通道从任意一个传送站前往任意的另一个传送站。也就是说,所有的传送站都会被通道所连通。

    三组通道按照 (1)(2)(3) 的顺序轮流运行,循环反复。在任意一个时刻,都有且只有一组传送通道可以使用。形式化地,在第 (i) 天中,有且只有第 (((i-1)) mod (3+1)) 组通道运行。

    C 国著名科学家 Access Globe 正在进行一项社会调查实验:调查两个传送站之间的传送通道使用者的信息。 Access Globe 的计划是这样的:

    • 选定两个传送站 (a)(b)

    • 第一天,他从 (a) 出发,使用正在运行的这组通道沿最短路径到达 (b),并调查经过的所有通道上使用者的信息

    • 第二天,他从 (b) 出发,使用正在运行的这组通道沿最短路径到达 (a),并调查经过的所有通道上使用者的信息

    • 第三天,他从 (a) 出发,使用正在运行的这组通道沿最短路径到达 (b),并调查经过的所有通道上使用者的信息

    Access Globe 知道每一条传输线路在运行时的使用者人数。他希望找出一对 (a)(b),使得在整个实验过程中所有经过的通道的使用者数量之和最大。

    Access Globe 希望参加 CCF NOI 2018 冬令营的你帮他解决这个简单的小问题。如果你成功地解决了这个问题, Access Globe 会送你一份小礼物——(100) 分!

    (2 leq n leq 10^5,0 leq w leq 10^{12})


    谁说边分治能干的点分治干不了?我点分治一样过好吧。

    先考虑边分治的做法,我们对第一棵树边分治,每次得到两个联通块的时候,对联通块黑白染色,考虑不同联通块跨越中心边的贡献。

    设中心边端点是 (x,y) ,对于颜色不同的两个点 (u,v) ,我们有 (dis_1(u,x)+w(x,y)+dis_1(y,v)+dep_2(u)+dep_2(v)+2dep_2(lca(u,v))+dep_3(u)+dep_3(v)+2dep_3(lca(u,v))) ,其中 (dep_x)(x) 到根的权值和,(w) 是常数,我们先拿掉,然后考虑对第二棵树建虚树,枚举 (lca) ,对于第三棵树,我们可以用dp来求出最值。

    假设现在在第二棵树上枚举到了点 (p) ,那么 (p) 不同子树的 (lca) 就是 (p) ,我们在第三棵树上每个点 (u) 连向一个虚点,边权为 (dis(u)=dis_1(u,x)+dep_2(u)) ,考虑在第三棵树上维护直径,维护出来颜色不同的两个点集的直径 (f_{u,0/1}) ,然后用不同颜色的 (f) 来更新答案,也就是 (max(f_{p,0}+f_{v,1},f_{p,1}+f_{v,0})+w(x,y)-2dep_3(lca(u,p))) ,这里 (f) 的加法是合并直径。

    复杂度 (O(nlog^2 n))

    这题之所以用边分治是因为我们每次要合并两个联通块,而点分治没法每次只分出来两个联通块。

    那么我们就规定一个合并联通块的顺序,来保证复杂度。

    考虑使用合并果子的方法,每次只合并两个点数最小的联通块,如果每次合并和计算的复杂度都是 (O(size_x+size_y)) ,那么复杂度仍然是 (O(nlog n))

    证明的话,我们对合并过程建哈夫曼树,一个点数为 (s) 的联通块在哈夫曼树的深度是 (log frac{n}{s}) ,那么我们写出来复杂度:

    [egin{aligned}T(u)&=sum_{vin son(u)}size_vlog n-sum_{vin son(u)}size_vlog size_v+sum_{vin son(u)}T(v)\&=size_ulog n-sum_{vin son(u)}size_vlog size_v+sum_{vin son(u)}T(v)end{aligned} ]

    我们会发现这样迭代下去中间的一项会两两减掉,那么就只剩了 (T(n)=sum_{vin son(u)}size_vlog n=nlog n)

    由于我写的代码又丑又长,所以我就放剪贴板了。

    边分治

    点分治

  • 相关阅读:
    Leetcode:50. Pow(x, n)
    loj 2759「JOI 2014 Final」飞天鼠
    bzoj 3569 DZY Loves Chinese II
    CF407D Largest Submatrix 3
    bzoj 3837 pa2013 Filary
    bzoj 4722 由乃
    CF1105E Helping Hiasat
    loj 6043「雅礼集训 2017 Day7」蛐蛐国的修墙方案
    luogu P2605 [ZJOI2010]基站选址
    luogu P3226 [HNOI2012]集合选数
  • 原文地址:https://www.cnblogs.com/sdlang/p/14510615.html
Copyright © 2011-2022 走看看