树上路径的交和并

前言

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

路径求交

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

树上路径求交

给出两条路径 \((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\neq 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_1\cup A_2\cup ... \cup A_m|=\sum\limits_{\{i\}}{|A_i|}-\sum\limits_{\{i,j\}}{|A_i\cap A_j|}+\sum\limits_{\{i,j,k\}}{|A_i\cap A_j\cap A_k|}+...+(-1)^{m+1}|A_1\cap A_2\cap ... \cap A_m|\)

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

例题:

BZOJ3589 动态树

树上直径合并

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

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

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

例题:暂无。

一点其它的做法

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

posted @ 2021-08-25 15:56  __Anchor  阅读(332)  评论(0编辑  收藏  举报