缝合怪
如题,缝合怪。
前置知识:题目标签里的所有算法,并确保透彻掌握。
距离 \(u\) 不超过 \(k\) 的点集(或距离 \(u\) 恰好为 \(k\) 的点集)称作“树上圆问题”,是点分治的模板;最大点异或是 01trie 的模板。但是点分治还需要一些奇怪的约束,导致还要多一个 cdq 分治的 log。
考虑当前在分治中心 \(rt\) ,结点深度用 \(dep\) 表示。处理到点 \(u\) 上的一个询问,参数为 \(k\) 与 \(x\),那么我们需要找一个点 \(v\) ,满足:
- 点 \(v\) 与点 \(u\) 不在同一子树内。
- \(dep_v+dep_u\leq k\) ,即 \(dep_v\leq k-dep_u\) 。
- \(a_v \text{xor}{x}\) 取得最大值。
只考虑 \(2,3\) 的话,显然是一个 可持久化01trie 可解决的问题,按照深度插入即可。关于点分治要求的 \(1\) ,一般有两种处理方法:
- 删除子树:把分治块内的点全部插入,处理该子树时,把该子树中的点暴力删除,处理完再加回来。但是众所周知,可持久化数据结构不支持删除。舍去。
- 处理前后缀:按子树顺序与逆序插入两次,处理该子树时,在前缀与后缀中分别查询。但是 可持久化01trie 强制要求按照深度插入,舍去。
怎么办呢?我们想办法一般地理解 \(1\) 限制。dfs 当前连通块并记下每个点的 \(dfn\) 序,记进入 \(u\) 子树的 \(dfn\) 为 \(st_u\),出去的为 \(ed_u\),那么 \(1\) 就表述为:
\[(dfn_v<st_u)\lor(dfn_v>ed_u)
\]
这个可以通过两次 cdq 分治实现。具体地,以 \(dfn_v<st_u\) 为例:
按照(结点的 \(dfn\) 序,询问的 \(st\) 值)分治。处理时按照 (结点的 \(dep\),询问的 \(k-dep\))排序。再加上普通的 01trie 就好了。
因为这题过于模板,加上码量会很大,数据也会比较难造(很可能三只 log 跑不过 n^2),因此暂时就丢在这里了。希望大家可以通过这题加强对这三个算法的理解。
如果有更优的做法,请务必告知。
 
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号