def s_for_prime_power(p, e):
k = 0
while e > p:
k += p
e -= p + 1
t = k // p
while t % p == 0:
t //= p
e -= 1
return (k + max(0, e)) * p
def div_of_factorials(start, limit):
small_prime_limit = limit ** 0.5
small_primes = []
half = limit // 2
s = [0] * (limit + 1)
m = 2
for m in range(2, half + 1):
if s[m] == 0:
s[m] = m
if m <= small_prime_limit:
small_primes.append(m)
s_m = s[m]
threshold = limit // m
for p in small_primes:
if p > threshold:
break
if m % p:
s[p * m] = s_m
else:
e, q = 2, m // p
while q % p == 0:
e += 1
q //= p
s[p * m] = max(s_for_prime_power(p, e), s[q])
break
for i in range(m, limit + 1):
if s[i] == 0:
s[i] = i
return sum(s[start:])
assert div_of_factorials(0, 10) == 5
assert div_of_factorials(0, 25) == 10
assert div_of_factorials(0, 100) == 2012
print(div_of_factorials(6, 10))
print(div_of_factorials(6, 10000))
ZGVmIHNfZm9yX3ByaW1lX3Bvd2VyKHAsIGUpOgogICAgayA9IDAKCiAgICB3aGlsZSBlID4gcDoKICAgICAgICBrICs9IHAKICAgICAgICBlIC09IHAgKyAxCiAgICAgICAgdCA9IGsgLy8gcAoKICAgICAgICB3aGlsZSB0ICUgcCA9PSAwOgogICAgICAgICAgICB0IC8vPSBwCiAgICAgICAgICAgIGUgLT0gMQoKICAgIHJldHVybiAoayArIG1heCgwLCBlKSkgKiBwCgpkZWYgZGl2X29mX2ZhY3RvcmlhbHMoc3RhcnQsIGxpbWl0KToKICAgIHNtYWxsX3ByaW1lX2xpbWl0ID0gbGltaXQgKiogMC41CiAgICBzbWFsbF9wcmltZXMgPSBbXQogICAgaGFsZiA9IGxpbWl0IC8vIDIKCiAgICBzID0gWzBdICogKGxpbWl0ICsgMSkKICAgIG0gPSAyCgogICAgZm9yIG0gaW4gcmFuZ2UoMiwgaGFsZiArIDEpOgogICAgICAgIGlmIHNbbV0gPT0gMDoKICAgICAgICAgICAgc1ttXSA9IG0KCiAgICAgICAgICAgIGlmIG0gPD0gc21hbGxfcHJpbWVfbGltaXQ6CiAgICAgICAgICAgICAgICBzbWFsbF9wcmltZXMuYXBwZW5kKG0pCgogICAgICAgIHNfbSA9IHNbbV0KICAgICAgICB0aHJlc2hvbGQgPSBsaW1pdCAvLyBtCgogICAgICAgIGZvciBwIGluIHNtYWxsX3ByaW1lczoKICAgICAgICAgICAgaWYgcCA+IHRocmVzaG9sZDoKICAgICAgICAgICAgICAgIGJyZWFrCgogICAgICAgICAgICBpZiBtICUgcDoKICAgICAgICAgICAgICAgIHNbcCAqIG1dID0gc19tCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBlLCBxID0gMiwgbSAvLyBwCgogICAgICAgICAgICAgICAgd2hpbGUgcSAlIHAgPT0gMDoKICAgICAgICAgICAgICAgICAgICBlICs9IDEKICAgICAgICAgICAgICAgICAgICBxIC8vPSBwCgogICAgICAgICAgICAgICAgc1twICogbV0gPSBtYXgoc19mb3JfcHJpbWVfcG93ZXIocCwgZSksIHNbcV0pCiAgICAgICAgICAgICAgICBicmVhawoKICAgIGZvciBpIGluIHJhbmdlKG0sIGxpbWl0ICsgMSk6CiAgICAgICAgaWYgc1tpXSA9PSAwOgogICAgICAgICAgICBzW2ldID0gaQoKICAgIHJldHVybiBzdW0oc1tzdGFydDpdKQoKCmFzc2VydCBkaXZfb2ZfZmFjdG9yaWFscygwLCAxMCkgPT0gNQphc3NlcnQgZGl2X29mX2ZhY3RvcmlhbHMoMCwgMjUpID09IDEwCmFzc2VydCBkaXZfb2ZfZmFjdG9yaWFscygwLCAxMDApID09IDIwMTIKCnByaW50KGRpdl9vZl9mYWN0b3JpYWxzKDYsIDEwKSkKcHJpbnQoZGl2X29mX2ZhY3RvcmlhbHMoNiwgMTAwMDApKQ==