计算范围 [L,R] 中可被范围 [1,N] 中的至少一个质数整除的数字的高效算法
Efficient algorithm to count the numbers in range [L,R] that are divisible by at least one prime number in range [1,N]
给定 N、L 和 R,我必须找出范围 [L,R] 中至少可被范围 [1,N] 中的一个质数整除的数字的个数。
约束条件:
1<=N<=50
1<=L,R<=10^18
示例:
N=5
L=1
R=10
答案 = 8
解释:
[1,5] 范围内的素数是 {2,3,5}。
[1,10] 范围内至少可被 {2,3,5} 中的一个素数整除的数是 {2,3,4,5,6,8,9,10}.
我在 Python 中的代码给出了 "Time Limit Exceeded" 错误,因为约束太高了!
我的代码:
import math
def primes_till_n(n):
sieve=[True]*n
for i in xrange(3,int(n**0.5)+1,2):
if sieve[i]:
sieve[i*i::2*i]=[False]*((n-i*i-1)/(2*i)+1)
return [2]+[i for i in xrange(3,n,2) if sieve[i]]
n,l,r=map(int,raw_input().split())
primes=primes_till_n(n+1)
ct=0
for i in xrange(l,r+1):
for j in primes:
if i%j==0:
ct+=1
break
print ct
此问题来自 Globalsoft hiring challenge,Hackerearth,挑战现已结束,未提供社论!
令素数数组包含小于 50 的素数。素数数组的大小将为 15。您可以计算区间 [L,R] 中有多少数可以被复杂度为 O(1) 的数整除(calculateInterval 函数在下面的代码中)。所以你应该对每个必要的素数做同样的事情。但是您应该执行包含排除以获得正确的结果。复杂度为 O(2^P)。 P 是不大于 N 的素数个数。2^P 最大为 2^15。
N, L, R, = map(int,raw_input().split())
def calculateInterval(begin,end,number):
return (end/number) - ((begin-1)/number)
primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
end = 0
while end < 15:
if primes[end] > N:
break
end += 1
res = 0
i = 1
while i < (1<<end):
cnt = 0
num = 1
for j in xrange(end):
if (1<<j) & i:
cnt += 1
num *= primes[j]
if cnt%2 == 1:
res += calculateInterval(L,R,num)
else:
res -= calculateInterval(L,R,num)
i += 1
print res
给定 N、L 和 R,我必须找出范围 [L,R] 中至少可被范围 [1,N] 中的一个质数整除的数字的个数。
约束条件:
1<=N<=50
1<=L,R<=10^18
示例:
N=5
L=1
R=10
答案 = 8
解释:
[1,5] 范围内的素数是 {2,3,5}。 [1,10] 范围内至少可被 {2,3,5} 中的一个素数整除的数是 {2,3,4,5,6,8,9,10}.
我在 Python 中的代码给出了 "Time Limit Exceeded" 错误,因为约束太高了!
我的代码:
import math
def primes_till_n(n):
sieve=[True]*n
for i in xrange(3,int(n**0.5)+1,2):
if sieve[i]:
sieve[i*i::2*i]=[False]*((n-i*i-1)/(2*i)+1)
return [2]+[i for i in xrange(3,n,2) if sieve[i]]
n,l,r=map(int,raw_input().split())
primes=primes_till_n(n+1)
ct=0
for i in xrange(l,r+1):
for j in primes:
if i%j==0:
ct+=1
break
print ct
此问题来自 Globalsoft hiring challenge,Hackerearth,挑战现已结束,未提供社论!
令素数数组包含小于 50 的素数。素数数组的大小将为 15。您可以计算区间 [L,R] 中有多少数可以被复杂度为 O(1) 的数整除(calculateInterval 函数在下面的代码中)。所以你应该对每个必要的素数做同样的事情。但是您应该执行包含排除以获得正确的结果。复杂度为 O(2^P)。 P 是不大于 N 的素数个数。2^P 最大为 2^15。
N, L, R, = map(int,raw_input().split())
def calculateInterval(begin,end,number):
return (end/number) - ((begin-1)/number)
primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
end = 0
while end < 15:
if primes[end] > N:
break
end += 1
res = 0
i = 1
while i < (1<<end):
cnt = 0
num = 1
for j in xrange(end):
if (1<<j) & i:
cnt += 1
num *= primes[j]
if cnt%2 == 1:
res += calculateInterval(L,R,num)
else:
res -= calculateInterval(L,R,num)
i += 1
print res