点分治 + bitset + 乱搞
模板题当然是要乱搞的啦,这边提供一种使用点分治,bitset 的乱搞方法。
考虑需要在线查询,所以建出点分树。
设当前查询点为 $(u,v)$ ,其在点分树上的 LCA 为 $rt$ ,即在一次点分治中以 $rt$ 为分治重心找到处在不同子树内的 $u,v$。此时只需要将 $(u,rt),(v,rt)$ 的答案合并一下就可以了。这个答案可以用 bitset 预处理。
这样做时间复杂度是 $O(\frac{(m+n\log n)n}{w})$,问题不大。
然而空间是 $O(\frac{n^2\log n}{w})$ 的,很遗憾无法通过。
这个时候借用一下正解撒点的套路,如果我们只记录某些点的答案,中间暴力往 bitset 中加入答案就好了。
这边我直接按深度每隔 $8$ 个点打一次答案,这样查询的时候也就只需要向上跳 $8$ 次答案就能找到了。
时空复杂度是玄学的,因为很有可能某个深度的点非常多,也许再随机一点会更好。不过即使不开 O2 这样也能过。
1 | #include<bits/stdc++.h> |

