我想在10个N元素的数组中存储大集合{1,2,....,10}中每个数字可被整除的值的数量,并进行累加求和得到可被整除的值的数量在O(1)时间内任何范围内的任何特定数字,例如,如果它需要获得可被以下至少一项整除的值的数量:2,3,5,那么我添加每个可被整除的值的数量然后删除交叉点,但我没有正确地弄清楚如何计算交叉点,每次没有2 ^ 10或2 ^ 9计算,这也将非常慢(并且可能耗费大量内存),因为它可能会完成100000次,有什么想法吗?
答案 0 :(得分:0)
你的想法是正确的。您可以使用包含 - 排除原则和前缀和来查找答案。你需要再做一次观察。
如果集合中有一对数字a
和b
,a
除以b
,我们可以删除b
而不更改答案查询(实际上,如果是b | x
,那么a | x
)。因此,我们总是得到一个集合,使得任何元素都不会划分任何其他元素。
此类掩码的数量小于2^10
。事实上,它是102
。这是计算它的代码:
def good(mask):
for i in filter(lambda b: mask & (1 << (b - 1)), range(1, 11)):
if (any(i % j == 0 for j in filter(lambda b: mask & (1 << (b - 1)), range(1, i)))):
return False
return True
print(list(filter(good, range(1, 2 ** 10)))))
因此,我们预处理需要大约100N
个操作和数字来存储(它看起来相当小)。
此外,任何“好”掩码中都有大多数5
个元素(可以使用上面的代码进行检查)。因此,我们可以使用2^5
操作来回答每个查询。