我想出了这个问题。
有一种加密算法,它广泛使用按位XOR运算。该加密算法使用一系列非负整数x 1 ,x 2 ,... x n 作为关键字。为了有效地实现该算法,Xorq需要为给定的整数a,p和q找到(a xor x j )的最大值,使得p <= j <= q。帮助Xorq实现此功能。
输入
第一行输入包含单个整数T(1 <= T <= 6)。 T测试案例如下。
每个测试用例的第一行包含由单个空格分隔的两个整数N和Q(1 <= N <= 100,000; 1 <= Q <= 50,000)。下一行包含N个整数x 1 ,x 2 ,... x n 由单个空格分隔(0 <= x j &lt; 215)。接下来的Q行中的每一行描述由三个整数组成的查询a i ,p i 和q i (0&lt; = a i &lt; 215,1&lt; = p i &lt; = q i &lt; = N)。
输出
对于每个查询,打印(a i xor x j )的最大值,使得p i &lt; = j&lt; = q i 在一行中。
示例输入
1 15 8 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 10 6 10 1023 7 7 33 5 8 182 5 10 181 1 13 5 10 15 99 8 9 33 10 14
样本输出
13 1016 41 191 191 15 107 47
解释
First Query (10 6 10): x6 xor 10 = 12, x7 xor 10 = 13, x8 xor 10 = 2, x9 xor 10 = 3, x10 xor 10 = 0, therefore answer for this query is 13. Second Query (1023 7 7): x7 xor 1023 = 1016, therefore answer for this query is 1016. Third Query (33 5 8): x5 xor 33 = 36, x6 xor 33 = 39, x7 xor 33 = 38, x8 xor 33 = 41, therefore answer for this query is 41. Fourth Query (182 5 10): x5 xor 182 = 179, x6 xor 182 = 176, x7 xor 182 = 177, x8 xor 182 = 190, x9 xor 182 = 191, x10 xor 182 = 188, therefore answer for this query is 191.
我首先考虑数字长度(二进制) 在给定的范围内相等,然后比较'a'位 用特定的xj值来表示。但是时间超过了。 java中的最大时间限制为5秒。
答案 0 :(得分:1)
我没有详细介绍你的代码,但你似乎在r = p - 1的范围内有循环; r&lt; q - 1; r ++,不必这样做会很好。
给定ai,我们希望在给定范围内找到xi的值,其顶部位数尽可能多于ai的倒数。一切都在0到2 ^ 15之间,因此没有多少比特需要担心。对于n = 1到15,您可以根据其n个最高位将xi分割,从而将其分成2,4,8,16 ... 32768个部分。对于每个部分,按照每个可能值的位置的排序顺序保留一个列表,因此对于顶部位,您将有两个列表,一个给出位模式为0的位置......... .....和一个给出位模式为1的位置............对于每个三元组,你可以在特定部分使用二进制斩波来查找是否有任何位置前n位具有您正在寻找的位模式的范围。如果他们这样做,那很好。如果不是,你将不得不接受其中一个xor位置为0并略微修改你寻找的模式,再设置一个顶部位。
设置成本是在xi上的15次线性传递,这可能比你读取它的时间要少。对于每一行你可以做15个二进制斩,看看xi的哪些值在前n位匹配,如果无法匹配特定位,请修改您查找的最高位模式。
如果通过将问题代码作为单独的子例程将I / O与问题代码分开,我认为您的程序会更清晰。这样也可以更容易地将问题代码的一个版本与另一个版本进行比较,看看哪个版本更快,如果它们都得到相同的答案。
答案 1 :(得分:1)
我在原始算法中发现的最大低效率是N
最多可达100,000,但a
和x
最多只能达到214.所以我会写伪代码像这样的东西:
bool set[256] = { false };
for (j = p; j <= q; j++) set[x[j]] = true;
for (k = 255; !set[a ^ j]; k--);
return k;
在最坏的情况下,这会将xor
操作的数量减少到256个。