zoukankan      html  css  js  c++  java
  • 树上路径的交和并

    前言

    作者讨论目前自己遇到的这一类问题的相关做法,并不代表没有更一般的问题和更优秀的做法,欢迎补充。

    路径求交

    因为这样类似的问题似乎很常见,所以这里讨论一下。

    树上路径求交

    给出两条路径 ((a,b),(c,d)) 四个点两两求 (LCA),得到 (x_1=lca(a,c),x_2=lca(a,d),x_3=lca(b,c),x_4=lca(b,d))

    从这四个点钟选择两个深度最大的点 (p_1,p_2)(p_1 eq p_2) 那么一定有交 交点分别为 (p_1,p_2)

    (p_1=p_2)(p_1) 的深度小于 (lca(a,b))(lca(c,d)) 那么两条路径无交点 否则交点为 (p_1)

    复杂度瓶颈在于求 (lca)

    例题:

    BZOJ3589 动态树(其实是需要转化才能变成求交的,详见下文)

    路径求并

    树上路径求并

    根据容斥原理,我们可以把路径求并转化为路径求交,也就是这个公式:

    集合 (S) 中至少具有性质 (large P_1,P_2,...,P_m) 之一的对象个数为 :

    (large |A_1cup A_2cup ... cup A_m|=sumlimits_{{i}}{|A_i|}-sumlimits_{{i,j}}{|A_icap A_j|}+sumlimits_{{i,j,k}}{|A_icap A_jcap A_k|}+...+(-1)^{m+1}|A_1cap A_2cap ... cap A_m|)

    但是这样做的弊端在于把问题变成了 (2^m) 个集合求交问题,所以这样做的复杂度是 (O(2^m imes k)) ,其中 (k) 是求一次两点 (lca) 的复杂度,(m) 是这次路径求并的路径条数。

    例题:

    BZOJ3589 动态树

    树上直径合并

    给出两颗树,并分别知道它们的直径两点,新的直径一定诞生在四个点的两两组合当中。

    根据直径的性质来贪心可以证明。

    复杂度瓶颈同样在于求 (lca)

    例题:暂无。

    一点其它的做法

    似乎都可以使用 (bitset) 来暴力做这些问题,但是复杂度似乎不太理想。

  • 相关阅读:
    windows 程序设计自学:窗口正中显示Hello,World
    为网站图片增加延迟加载功能,提升用户体验
    线性表顺序存储
    sys.stdout sys.stderr的用法
    python 跳出嵌套循环方法
    * 与 ** 在调用函数时的作用
    twisted 学习笔记二:创建一个简单TCP客户端
    给命令行上色
    __new__ 的简单应用
    网友对twisted deferr的理解
  • 原文地址:https://www.cnblogs.com/Akmaey/p/15185441.html
Copyright © 2011-2022 走看看