给出数组中的一系列随机数,例如:147, 95, 254, 78, 66, 120
,当它们为{{1时,如何找到从索引n
到索引m
的操作数的结果}}(按位&)有效?
例如:
&
和n = 2
。这意味着您必须m = 5
从第二个元素(&
)到第五个元素(95
)的数组中的数字。
除了只66
一个一个地&
之外,我不知道该怎么做,但这并不高效。我正在处理的问题有多个查询,这意味着使用一系列随机数(例如上述内容),该问题可能会问&
元素的数字的n
结果多次直到m
元素,并且每个查询包含n
和m
的不同值。
编辑:我尝试执行以下操作:将所有数字更改为二进制位并将所有位存储为双端队列。之后,检查给定范围内的位之一是否为0,如果存在一个0,则该位返回0值。我确实得到了正确答案。但是,它仍然不够高效。 Here是我的代码
答案 0 :(得分:6)
可以用k个范围和查询来完成,其中k是以位为单位的元素的大小:
对于每个位,请执行范围和查询。如果结果小于跨度的长度,则结果中的该位为零,否则为1。这些可以很容易地通过k个前缀和数组来完成,尽管与输入相比,它们的存储量相当大。
很明显,这里的想法是为每个元素的正好最低有效位添加一个前缀和数组(对它的查询会计算结果的lb),另一个只是第二个比特,依此类推,直到k。
前缀-AND数组不能以相同的方式使用,例如,考虑第一个元素是否为零,但是可以工作的单词级替代方法是横向堆。这仅需要一个实际查询(尽管更为复杂),并且仅占输入空间的两倍(尽管四舍五入为2的幂)。这需要一个奇特的“双面查询”,即您从两片叶子上锁步地爬上树,并在它们的LCA相遇时停下来(此时,端点之间的范围已被覆盖,仅此而已)。更多信息in this other answer。
这两个选项可能仅对竞争性编程有用,因为它们故意使幼稚的算法在疯狂的大型查询上受阻。