1.24 两道树上问题的解法与思考

内容过于简单,勿喷。

勘误:access 次数是 \(O(n \log n)\) 的,所以 2.2 不存在单 log 做法。

1.1 P6072 Path(双 log)

选择两条简单路径,满足没有重合的点,且边权异或和之和最大。\(n\le 10^5\)

我们可以把问题转化为选出一个 \(u\),令在子树内选出两个点的异或和最大为 \(f_u\),子树外为 \(g_u\),那么我们需要求 \(f_u+g_u\) 的最大值。

首先,通过 DSU on tree,我们可以搞出一种比较巨大的双 log 做法。不多赘述。

1.2 P8511 [Ynoi Easy Round 2021] TEST_68

本题需要求出所有 \(g_u\),但是复杂度单 log。

考虑如下做法:首先找到全局的最优的链 \((x,y)\)。我们发现,对于不在 \(1\to x\)\(1\to y\) 路径上的点,\(g_i\) 一定是 \((x,y)\) 这条路径。

现在问题转化为对于一条 \(1\to x\) 的路径进行求解。这是容易的,考虑从 \(1\to x\) 走的时候,“子树外”这个集合是不断扩大的,暴力增加即可。

1.3 P6072 Path(单 log)

我们回到第一个问题上。现在我们已经能够单 log 求出所有 \(g\)。求出所有 \(f\) 看上去不能够利用以上解法得到单 log 解。

但是由于我们需要求的是最大的 \(f+g\)。于是对于 \(g\) 相同的 \(u,v\),若 \(v\in T_u\) 那么 \(v\) 没有任何用处。所以,我们实际上需要求出的 \(f\) 只有一些极大的子树,以及 \(1\to x\)\(1\to y\) 的链。两者都是好求的,于是总复杂度 \(O(n\log n)\)

2.1 LOJ6041 事情的相似度(双 log)

给定 01 串,令 \((i,j)\) 的贡献表示为 \(i\) 起始的后缀与 \(j\) 起始后缀的 LCP,每次问询求区间两两贡献的最大值。

通过建立后缀树,转化为区间两两 lca 的最大深度。

首先,我们有一种双 log 的做法。考虑我们在 lca 处统计贡献。进行 DSU on tree,并且在遍历轻子树时,将其在重子树中的(标号的)前驱后继找出。于是我们可以发现,有用的点对一定产生于这些中,只有 \(O(n\log n)\) 个。于是总复杂度 \(O(n\log^2 n)\)

2.2 LOJ6041 事情的相似度(跑的更快的双 log)

在“本质不同子串个数”一题中,我们有了在后缀树上扫描线做 access 操作的想法。这个想法同样可以运用于这题。

考虑扫描线的同时,维护这个点的贡献。考虑每次到 \(r\) 做一次类似 access 操作,给祖先点染颜色 \(r\)。那么如果一个节点先前染色为 \(l\),那么就把 \((l,r)\) 加入点对集中。由于 access 更改次数单 log,所以总复杂度为 \(O(n\log^2 n)\)

在 LOJ 上这个解法跑的非常快。大概是因为字符串题 access 操作比较难以卡满。

3 总结

讲真我觉得这两题关系不大,但是关系很大。

所以没啥好总结的吧。但是确实很有趣。以前并不熟悉这些技巧。

posted @ 2024-01-24 21:32  LarsWerner  阅读(7)  评论(0编辑  收藏  举报