from sys import stdin
import math
# 先用篩法建一小段質數
u = 100
sieve = [0, 0, 2, 3] + [1] * (u - 4)
prime = [2]
for i in range(3, u, 2):
if(sieve[i] == 0): continue
prime.append(i)
for j in range(i * i, u, i):
sieve[j] = 0
#######################
def isPrime(n):
'''
參考 http://www.csie.ntnu.edu.tw/~u91029/Prime.html
質數判定
'''
if(n == 2): return 1
if(n%2 == 0): return 0
if(n%6 not in [1,5]): return 0
u = n - 1
t = 0
while(u % 2 == 0):
u >>= 1
t += 1
sprp = [2, 7, 61]
for sk in sprp:
a = sk % n
if (a == 0 or a == 1 or a == n-1): continue
x = pow(a, u, n)
if (x == 1 or x == n-1): continue
for i in range(t-1):
x = pow(x, 2, n)
if (x == 1): return 0
if (x == n-1): break
if (x != n-1): return 0
return 1
def factorize(n):
# 因數分解
# 參考網路上的解法,非原創
if(isPrime(n)): return 1, n, 1
x_fixed = 2
cycle_size = 2
x = 2
factor = 1
while factor == 1:
count = 1
while count <= cycle_size and factor <= 1:
x = (x*x + 1) % n
factor = math.gcd(x - x_fixed, n)
count += 1
cycle_size *= 2
x_fixed = x
c = 0
while(n % factor == 0):
n //= factor
c += 1
return n, factor, c
def 計算因數(n):
if(n == 1): return 1
if(isPrime(n)): return 2
k = int(n ** 0.5) # 上限
r = 1
for x in prime:
if(x > k): break
c = 0
while(n % x == 0):
c += 1
n //= x
r *= (c + 1)
'''
先用建立好的一小段質數表試除
剩餘的用 factorize 分解
'''
while(n > 1):
n, y, z = factorize(n)
r *= (z + 1)
if(n == 1): break
return r
N = int(stdin.readline()) # 測資筆數
for i in range(N):
L, U = map(int, stdin.readline().split())
P, D = 0, 0
for j in range(L, U+1):
tmp = 計算因數(j)
if(tmp > D):
P, D = j, tmp
print('Between {} and {}, {} has a maximum of {} divisors.'.format(L, U, P, D))
2020/03/04
[zerojudge] d366: 00294 - Divisors
訂閱:
張貼留言 (Atom)
沒有留言:
張貼留言