本题做法:树链剖分 + 线性基。
没有学过树链剖分和线性基?左转我的树链剖分学习笔记,右转我的线性基学习笔记。
下面默认读者学会了树链剖分与线性基。
首先对于 Query 操作,我们需要转化一下题意:对于路径上的点而言,是否能够选出一些点,使得这些点点权异或值为 0。
这么做的理由是因为如果不存在这样的点集,那么就不会出现两个不相同的集合其异或值相同。
看到异或值询问是否有 0,这是线性基的基本操作:如果有数插入失败,这说明有点集异或结果为 0。
因为点权的值域是
[
0
,
2
30
)
[0,2^{30})
[0,230),在这个值域范围下线性基的个数至多只有 30 个,因此对于所有路径大于 30 的询问全部都是 YES
。
小于等于 30 的询问呢?由于点数只有 30 个,显然可以暴力查找路径上的点,加入线性基即可。
对于 Update 操作,在树剖之后直接维护线段树,Update 即可。
对于 Query 操作,上面已经详细讲过了,只不过往线性基中加数的时候需要在线段树中单点查询。