### Sukarna_Paul's blog

By Sukarna_Paul, history, 13 months ago, ,

I have been trying to solve this problem for last few days . Here is the Problem link SPOJ PTRI .

I have used Linear sieve , but the limit is so high that it is getting TLE in O(N) . I have tried it with sieve of aktin also. But still got TLE . Please help me to solve this one.

I found this problem in -Morass- blog Link . You can visit it , I am confident that you will find it useful.

• +11

 » 13 months ago, # | ← Rev. 2 →   0 You can implement a segmented sieve of Eratosthenes.
•  » » 13 months ago, # ^ |   0 why so serious? I believe https://cp-algorithms.com/algebra/sieve-of-eratosthenes.html#toc-tgt-6 is more than enough for this problem
 » 13 months ago, # | ← Rev. 2 →   +6 For this problem you can do a lot of optimisation. You can solve the problem offline. You can read all queries, then sort them (by means of radix sort algorithm for example) Inside the sieve after getting sequent prime number you can compare it with current query number. If it is less then the current query number, you go to the next prime number. If it is equal to the current query number, you saved the position for this query and increment the current query index in the sorted list. If it is greater then the current query number, then you simply increment the current query index. So no need in binary search. Because we get the primes sequently we can know the row and column numbers offhand, just keeping two variables r and c. When we get next prime number we increment ++c. If c becomes greater than r we do ++r, c = 1. So no need in sqrt(). As for sieve itself. To reduce memory usage you can use bitwise operations (for example) with one bit on any number from interval [1... 108] or 12M in total (and no need in supporting the prime list). Also you can try linear sieve or segmented sieve (the codes can be found in this blog entry). UPD: One more fast sieve you can find here. I did not test all mentioned sieves on this problem, sorry.
•  » » 11 months ago, # ^ |   0 Alas, it turns out that a solution with $sqrt()$ and binary search is slightly faster than a solution with above optimizations. The problem can be solved by means of correctly written wheel sieve. Here is the code for the sieve with the base $( 2, 3, 5, 7 )$ which is fast enough to evade TLE: Wheel sieveconst int pd[48] = { 10,2,4,2,4,6,2,6,4,2,4,6,6,2,6,4,2,6,4,6,8,4,2,4,2,4,8,6,4,6,2,4,6,2,6,6,4, 2,4,6,2,6,4,2,4,2,10,2 }; #define LIMIT 100000000 #define HAS(_n) (pbits[(_n)>>6] & (1u << (((_n)>>1) & 0x1f))) #define SET(_n) (pbits[(_n)>>6] |= (1u << (((_n)>>1) & 0x1f))) unsigned int pbits[LIMIT/64+1]; void sieve( void ) { int i, j, id, jd; pr = pc = cur = 0; prime( 2 ); prime( 3 ); prime( 5 ); prime( 7 ); for( i = 11, id = 0; i < LIMIT; i += pd[id]) { if( !HAS(i) ) { prime( i ); if( i < 10000 ) { int limit = LIMIT / i; for( j = i, jd = id; j <= limit; j += pd[jd]) { int num = j * i; SET( num ); if( ++jd >= 48 ) jd = 0; } } } if( ++id >= 48 ) id = 0; } } 
•  » » » 7 weeks ago, # ^ |   -8 How to use this ?
•  » » » » 7 weeks ago, # ^ | ← Rev. 2 →   0 Seems something wrong is with this problem. Any my AC solution gives TLE now. Sorry.UPD: Solution with fast I/O was accepted. The execution time shifted from 0.22 to 0.29 sec though.