I have been trying to solve this problem for a while, but getting the wrong answer again and again. the number can be very large <= 2 2014. 22086. Prime Power Test
Explanation of my algorithm:
- For a given number, I check if the number can be represented as a form of primary power or not.
- Thus, the maximum limit for checking primary power is log n base 2.
- Finally, the problem boils down to finding the nth root from a number, and if it is simple, we have our answer, we will check for all
i up to log (n base 2) and exit . - I used all kinds of optimizations and tested huge test scripts, and the correct answer for all of my algorithm.
- but the judge says the wrong answer.
- Spoj has another similar problem with small restrictions n <= 10 ^ 18, for which I already adopted Python and C ++ (the best solver in C ++)
Here is my python code. Please suggest me if I do something wrong. I am not very versed in python, so my algorithm is a bit long. Thanks in advance.
My algorithm:
import math import sys import fractions import random import decimal write = sys.stdout.write def sieve(n): sqrtn = int(n**0.5) sieve = [True] * (n+1) sieve[0] = False sieve[1] = False for i in range(2, sqrtn+1): if sieve[i]: m = n//i - i sieve[i*i:n+1:i] = [False] * (m+1) return sieve def gcd(a, b): while b: a, b = b, a%b return a def mr_pass(a, s, d, n): a_to_power = pow(a, d, n) if a_to_power == 1: return True for i in range(s-1): if a_to_power == n - 1: return True a_to_power = (a_to_power * a_to_power) % n return a_to_power == n - 1 isprime=sieve(1000000) sprime= [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997] def smooth_num(n): c=0 for a in sprime: if(n%a==0): c+=1 if(c>=2): return True; return False def is_prime(n): if(n<1000000): return isprime[n] if any((n % p) == 0 for p in sprime): return False if n==2: return True d = n - 1 s = 0 while d % 2 == 0: d >>= 1 s += 1 for repeat in range(10): a=random.randint(1,n-1) if not mr_pass(a, s, d, n): return False return True def iroot(n,k): hi = 1 while pow(hi, k) < n: hi *= 2 lo = hi // 2 while hi - lo > 1: mid = (lo + hi) // 2 midToK = (mid**k) if midToK < n: lo = mid elif n < midToK: hi = mid else: return mid if (hi**k) == n: return hi else: return lo def isqrt(x): n = int(x) if n == 0: return 0 a, b = divmod(n.bit_length(), 2) x = pow(2,(a+b)) while True: y = (x + n//x)>>1 if y >= x: return x x = y maxx=2**1024;minn=2**64 def nth_rootp(n,k): return int(round(math.exp(math.log(n)/k),0)) def main(): for cs in range(int(input())): n=int(sys.stdin.readline().strip()) if(smooth_num(n)): write("Invalid order\n") continue; order = 0;m=0 power =int(math.log(n,2)) for i in range(1,power+1): if(n<=maxx): if i==1:m=n elif(i==2):m=isqrt(n) elif(i==4):m=isqrt(isqrt(n)) elif(i==8):m=isqrt(isqrt(isqrt(n))) elif(i==16):m=isqrt(isqrt(isqrt(isqrt(n)))) elif(i==32):m=isqrt(isqrt(isqrt(isqrt(isqrt(n))))) elif(i==64):m=isqrt(isqrt(isqrt(isqrt(isqrt(isqrt(n)))))) elif(i==128):m=isqrt(isqrt(isqrt(isqrt(isqrt(isqrt(isqrt(n))))))) elif(i==256):m=isqrt(isqrt(isqrt(isqrt(isqrt(isqrt(isqrt(isqrt(n)))))))) else:m=int(nth_rootp(n,i)) else: if i==1:m=n elif i==2:m=isqrt(n) elif(i==4):m=isqrt(isqrt(n)) elif(i==8):m=isqrt(isqrt(isqrt(n))) elif(i==16):m=isqrt(isqrt(isqrt(isqrt(n)))) elif(i==32):m=isqrt(isqrt(isqrt(isqrt(isqrt(n))))) elif(i==64):m=isqrt(isqrt(isqrt(isqrt(isqrt(isqrt(n)))))) elif(i==128):m=isqrt(isqrt(isqrt(isqrt(isqrt(isqrt(isqrt(n))))))) elif(i==256):m=isqrt(isqrt(isqrt(isqrt(isqrt(isqrt(isqrt(isqrt(n)))))))) else:m=iroot(n,i) if m<2: order=0 break if(is_prime(m) and n==(m**i)): write("%d %d\n"%(m,i)) order = 1 break if(order==0): write("Invalid order\n") main()