CF1902F Trees and XOR Queries Again 题解
前言
本题是简单的、一眼的、普通的、显然的。
正文
0x00 分析题目
给定一颗带点权无根树,每次询问给定两个点
u,v 和参数k ,回答是否有一个u\leftarrow v 简单路径的点权子集其异或和是k 。
可以肯定的是这个题需要线性基,以及线性基合并等知识,不会的推荐线性基学习笔记 | Menci's OI Blog。下文默认
0x01 树上倍增 \mathcal{O}\left(n\log^3{n}\right)
做法
首先考虑到一个显然的做法,树上倍增,对于每个
询问时,
代码实现
实测使用一定的常数优化可以轻松通过:
- 线性基插入一个数
x 时从\log_2 x 位开始枚举,每次插入后重新取\log_2 x 寻找下一位。 - 树上倍增时从
\log dep 开始倍增。 - 取
\log_2 x 使用31^__builtin_clz(x)计算最快。
AC CODE,最大点跑了
0x02 点分治做法 \mathcal{O}\left(n\log^2{n}\right)
做法
观察发现树上倍增做法之所以慢是应为我们钦定了两个点在他们的
具体的,对于每次点分治,处理跨越当前子树重心的所有询问。对于每个子树的点
思考,点分治的好处是每次查询只需要合并两个线性基,并且预处理不需要合并线性基所以可以得到更优的时间复杂度。
代码实现
加上前面的优化甚至可以跑进一秒,AC CODE。
总结
本题利用了点分治对询问优秀的拆分方式解决了本题。