范围内无平方数的计数

时间:2014-04-13 15:05:47

标签: algorithm math data-structures discrete-mathematics

给定两个数字xy,找到squarefree数字的数量,其中squarefree数字是一个可被整除的整数除以1除外。例如,10是无方形的,但18不是,因为它可以被9 = 32整除。很少有正方形数字:

1, 2, 3, 5, 6, 7, 10, 11, 13, 14, 15 ...

限制

1 <= X,Y <= 10^9

0 <= |X-Y| <= 10^6

x=10 , Y=15 

给出

ans=5

我的方法是生成所有素数直到squareroot(10^9)(eratosthenes筛),并检查给定范围内的每个数字是否可被素数平方整除。从范围长度中减去这些数字的数量,得到平方自由数。

但是这种方法的复杂性超时,请提出其他方法

2 个答案:

答案 0 :(得分:5)

使用inclusion-exclusion principle

f(n) = number of non-square-free numbers in 1 ... n。我们只对素数的正方形进行包含 - 排除,以避免对正方形的广义进行过度计数。

我们有:

f(n) = n / 4      => these are divisible by 4, so NOT square-free
       +
       n / 9      => these are divisible by 9, so NOT square-free
       + 
       n / 25     => these are divisible by 16, so NOT square-free
       +
       ...
       -
       n / (4*9)  => these are divisible by both 4 and 9, so we overcounted
       -
       n / (4*25) => these are divisible by both 4 and 25, so we overcounted 
       -
       ...

这有多高效?

我们只需要p这样的素数p^2 <= 10^9,意为p < 31623。这已经不是很多素数,任何微不足道的筛子(或者甚至是试验师)都应该足够快。然后应用包含 - 排除,这也很快,因为平方素数的乘积会快速变大,因此您可以在很多情况下提前终止(n / something = 0只要something > n

为了了解您为何能够提前终止,请将以上内容重写为:

f(n) = n / (2^2) -
       n / (2^2*3^2) +
       n / (2^2*3^2*5^2) -  <= this becomes 0 very fast. 
                               When it does, 
                               backtrack and increment the previous term.
                               For example, if this were 0,
                               you'd do - n / (2^2*5^2) next
       ...

有关此here的更多信息。

答案 1 :(得分:4)

扩展我的评论:假设X&lt; = Y并初始化布尔数组SF [X..Y]全部为真。对于从2到层的每个k(sqrt(Y))(可选地包括复合;渐近运行时间保持不变),对于X和Y之间的每k个k 2,将SF [m]设置为假。返回SF中剩余的真实值。

运行时间为O((Y - X)+ sqrt(Y)),因为Σ k = 1,...,∞ 1 /k²=π²/ 6。