树上路径的交和并

前言

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

路径求交

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

树上路径求交

给出两条路径 ((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) 来暴力做这些问题,但是复杂度似乎不太理想。

原文地址:https://www.cnblogs.com/Akmaey/p/15185441.html