prime interval(PRINT) on SPOJ - primes

I implemented a sieve for finding prime numbers between given range by first finding primes up to square root of highest possible number for upperlimit of interval and then for each test case find prime numbers up to required limit.I start marking composite from square of each prime.
This gets AC in SPOJ PRIME1( http://www.spoj.com/problems/PRIME1/ ) in 0.07 but gets TLE for PRIME INTERVAL-PRINT. (http://www.spoj.com/problems/PRINT/) How can I improve this?

Related

Algorithm of divisors

I am given a list of integers (up to 1000) which multiply to a given integer n .
I need to find the highest power among all the divisors of the integer n .
For instance : 4,7,8 multiply to 224 and the highest power will then be 5 since 224=2^2*7*2^3=2^5*7.
The problem is, the 1000 integers can be as large as 2^64, hence n is very large.
What is a great algorithm to solve this ?
Difficult. I'd start checking small primes first (in your example: 4, 7, 8. The product has a factor 2^5. You divide by the powers of two, leaving 1, 7, 1. Then you do the same for 3, 5, 7 etc. up to X).
Now you need to find a larger prime p > X that is a higher power than the highest you found. Spending lots of time to find prime factors that occur only once seems wasteful. You need primes that are factors of multiple numbers. Calculate the gcd of each pair of numbers and look at prime factors of these numbers. There are lots of details that need working out, that's why I started with "difficult".
Worst case you can't easily find any prime that occurs twice, so you need to check if each of the numbers contains the square of a prime as factor.
As an example: You checked for factors up to 1000, and you found that the highest power of a prime was 83^3. So now you need to find a larger prime that is a fourth power or show there is none. Calculate the pairwise gcd's (greatest common divisor). A large prime could be a divisor of multiple of these gcd's coming from four different numbers, or p could be factor of three gcd's, with p^2 a factor of one number etc.
To clarify the principle: Say you have two HUGE numbers x and y, and you want to know which is the highest power of a prime which divides xy. You could factor x and y and go from there. If they are both primes or products of two large primes, say x = p or pq, and y = r or rs, this takes a long time.
Now calculate the gcd of x and y. If the greatest common divisor is z > 1, then z is a factor of x and y, so z^2 is a factor of xy. If the greatest common divisor is 1, then x and y have no common factor. Since we don't need factors that are not square, we look for squares and higher factors. For that you only need to divide by factors up to x^(1/3) or y^(1/3).

Is there a more efficient way to generate Palindromes which are prime if the bounds are large?

I have solved this problem on USACO training about generating prime palindromes between a limit.I have quoted the problem transcript at the end. I solved it by generating all odd palindromes below the upper limit and checking each for prime printed them. The solution passed on the grader but is there an even efficient method than my noob generate all and check thing(for I really wish to learn more efficient strategies in competitive programming).
The number 151 is a prime palindrome because it is both a prime number and a palindrome (it is the same number when read forward as backward). Write a program that finds all prime palindromes in the range of two supplied numbers a and b (5 <= a < b <= 100,000,000); both a and b are considered to be within the range .
PROGRAM NAME: pprime
INPUT FORMAT
Line 1: Two integers, a and b
SAMPLE INPUT (file pprime.in)
5 500
OUTPUT FORMAT
The list of palindromic primes in numerical order, one per line.
SAMPLE OUTPUT (file pprime.out)
5
7
11
101
131
151
181
191
313
353
373
383
I guess I should also provide my algorithm for getting the output
Step 1. Take Input a and b
Step 2. Initialise a list of odd palindromes op
Step 3. Add 5, 7 and 11 to op
Step 4. Generate all the 3,5,7 digit odd palindromes and add to op
Step 5. Check for every element e of op
Step 5.1. If e>=a and e<=b
Step 5.1.1. If e is PRIME print e
Terminate the loop otherwise
Had the upper bound been larger this process would obviously have failed, therefore I am looking for a more efficient solution.
EDIT: I check for primes the usual way, as in
Given the number I've to check for prime is n.
if (n==1) return false;
if (n==2) return true;
for (int i = 2; i <= sqrt(n); ++i)
if (n%i == 0) return false;
return true;
Actually the way you checked for primality is quite efficient for small numbers, for checking the primality of bigger number, you can use primality tests, such as the Rabin Miller and the Baillie-PSW (BPSW or BSW) primality test. The thing is, those algorithm really looks magic, I've never even tried to understand how and why they work, but they do work pretty well ! With the later, I've been able to generate a 320 digits prime. You can easily find implementation of those algorithms online.

Factorize integer larger than 200 digits c++

I have to factorize a number given by text in C++, this number is greater than a double, and I can't use external libraries. I know this number is a product of the first 25 prime numbers. Is there a way I can process this number and give it's descomposition in prime?
Whats the best algorithim I could use to do so?

Primality test for numbers of form 10^n + k

I have some numbers of form 10N + K, where N is about 1000, and K is really small (lower than 500). I want to test these numbers for primality. Currently I'm using Fermat's test by base 2, preceded by checking small factors (<10000).
However, this is rather slow for my purposes. Is there any algorithm quicker than that? Can this special form be exploited somehow?
Also, maybe if two numbers differ only in K, is it possible to test these two numbers a bit quicker?
If K has a factor of either 2 or 5 then 10^N + K is composite. This allows testing a small number quickly. Large primes are all such that P mod 6 = 1 or 5. You can use this to eliminate 2/3 of possible K values. With a little work you can set up a 2-4 wheel to avoid a lot of division:
increment <- either 2 or 4 as required
repeat
K <- K + increment
increment <- 6 - increment
if (K mod 5 = 0) then
continue
endif
until (isPrime(10^N + K) or (K > 500))
Trial factoring up to 10,000 if fine. Are you building a list of the primes up to 10,000 first? Use Eratosthenes' Sieve to create the list and just read off numbers.
Running a Fermat Test base 2 is a good start, it finds a lot of composites reasonably quickly.
After that you need to implement the probabilistic Miller-Rabin test, and run it enough times that it is more probable your hardware has failed rather than the number is composite.
Also, maybe if two numbers differ only in K, is it possible to test these two numbers a bit quicker?
To check the primes in a relatively small interval like [10N+K1, 10N+K2]
you can use the sieve of Erathostenes to check for divisibility by small numbers.
The remaining prime candidates can then be checked by a probabilistic test like Miller-Rabin.

Computing different terms for a given pair of exponentiation having the same result

To understand the problem,let us consider these examples first:
                                 46 = (22)6 = 212 = (23)4 = 84 = 163 = 4096.
Thus,we can say that 46,212,84 and 163 are same.
                                 273 = 39 = 19683
so, both 273 and 39 are identical.
Now the problem is, for any given pair of ab how to compute all others possible (if any)xy where, ab = xy.I am interested in an algorithm that can be efficiently implemented in C/C++.
For example:
If the inputs are like this:
4,6 desired output :(2,12),(8,4)
8,4 desired output :(2,12),(2,6)
27,3 desired output :(3,9)
12,6 desired output :(144,3),(1728,2)
7,5 desired output : No duplicate possible
This is mostly a math problem. You can extract all the prime factors of a number, and you'll get a list of prime numbers and their exponents, i.e., 216000 = 26 * 33 * 53. Then take the GCD of the exponents: GCD(6,3,3) = 3. Divide the exponents by the GCD to get the smallest root of the number, 22 * 31 * 51 = 60. Then factor the GCD — factors of 3 are 1 and 3. There is one way to express the number as an integral power for each factor of the GCD. You can express it as (603)1 or (601)3.
EDIT: fixed math error.
If integers is the only thing you're interested in, you could just start extracting integer roots from the target number, and checking if the result is an integer.
You even have a convenient stop condition - whenever the root is below 2 you can stop. That is, the algorithm:
Given a result
N <- 2
Compute Nth root.
If it's an integer: add to answers
If it's < 2, exit loop
N += 1, back to previous step
This algorithm will always terminate.
I believe that this problem is equivalent to the Integer factorization problem.
I said this because we can convert any composite number to a unique product of prime numbers
(see Fundamental theorem of arithmetic) and then start creating combinations with the factors and the powers.
Update: for example: 46
we convert it to a power of a prime factor, so we have 212.
Now we increase the base exponentially and we have: 46, 84 ... until the exponent becomes 1.
I finally solved it myself.Using a naive integer factorization algorithm my solution look like this.It can be optimized further by using Pollard's rho algorithm
EDIT: Code updated, now it can handle composite bases.Please point if it has certain other bugs too :)
The smallest base that makes sense is 2. Also, the smallest exponent that makes sense is 2.
Given the result, you can determine the largest possible exponent.
Example: 4096 = 2^12, biggest exponent is 12.
This also works with results that aren't powers of 2: 19683 is a bit bigger than 2^14, so you won't be seeing any exponents bigger than 14.
Now you can take your number and work your way down from the top exponent toward 2 (the smallest exponent). For every trial exponent exp, take the exp-th root of the result; if that comes out as a clean integer, then you've found one solution.
You can use logarithms to calculate the log2 of a result, and to take the n-th root of a number. But you will need to watch out for rounding errors.
The advantage of this approach is that once you've set things up, you can just run down a simple loop, and once done you have all your results.