给定两个数字x
和y
,找到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筛),并检查给定范围内的每个数字是否可被素数平方整除。从范围长度中减去这些数字的数量,得到平方自由数。
但是这种方法的复杂性超时,请提出其他方法
答案 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。