题目描述
给定一个长度为 n 的数列 A1,A2,⋅⋅⋅,An 和一个非负整数 x,给定 m 次查询,每次询问能否从某个区间 [l,r] 中选择两个数使得他们的异或等于 x。
输入输出格式及数据范围
输入输出样例
思路
①对于两个数的异或值为x,可以化简为,在区间L和R之间,寻找一个数b,使得b = a ^ x
,此处我们不妨规定b < a
,指的是b的下标小于a。
②但是本题的数据范围是1e5,如果使用①的方法思考,那么时间复杂度为O(n2),会超时,我们需要将时间复杂度控制在O(nlogn)之内,因此需要一种优化方法。
③对于区间L~R
,我们不妨令①中的a为ai,这样我们总是需要寻找一个在ai左侧的b,b的下标需要大于等于L,如果存在这样的b,就可以说区间中存在满足题意的数对。令f[i]
为b的下标,即如果f[i] ≥ L
,则可以输出“yes”,否则输出“no”。
④但是按照③中的思路维护f[i]
,是在区间L和R中进行维护,L和R的自由度之和为O(n2),仍然不能满足题意,因此还需要进一步的优化。值得注意的是,由于我们认为约定b < a
(b的下标小于a,即b在a的左侧寻找),因此对于ai,如果a的下标i<L
,那么f[i]
自然会小于L,f存的是b的下标,b的位置一定在a的左侧,更不可能处于区间L和R之中。因此可以优化为在1~R
维护数组f,对于ai,由于其左侧可能有多个f[j]
满足大于L(但是这个f[j]可能不是由ai贡献的,而是位置比ai靠左的另一个数贡献的),因此可以另外维护数组g&