def is_prime_MR(n): if n in [2,7,61]: return True if n<2 or n%2==0: return False d=n-1 d=d//(d&-d) L=[2,7,61] if n<1<<32 else [2,3,5,7,11,13,17] if n<1<<48 else [2,3,5,7,11,13,17,19,23] if n<1<<61 else [2,3,5,7,11, 13,17,19,23, 29,31,37] for a in L: t=d y=pow(a,t,n) if y==1: continue while y!=n-1: y=(y*y)%n if y==1 or t==n-1: return False t<<=1 return True def prime_counter(n): i=2 ret={} mrFlg=0 while i*i<=n: k=0 while n%i==0: n//=i k+=1 if k: ret[i]=k i+=1+i%2 if i==101 and n>=2**20: while n>1: if is_prime_MR(n): ret[n],n=1,1 else: mrFlg=1 j=_find_factor_rho(n) k=0 while n%j==0: n//=j k+=1 ret[j]=k if n>1: ret[n]=1 if mrFlg>0: ret={x:ret[x] for x in sorted(ret)} return ret def divisors(n): """ O(x^1/4) O(10**9)の整数10**4個の約数列挙が可能 """ primes=prime_counter(n) P=set([1]) for key,value in primes.items(): Q=[] for p in P: for k in range(value+1): Q.append(p*pow(key,k)) P|=set(Q) return P def _find_factor_rho(n): m=1<