I know you can get an AC in problem with normally optimized prime sieve. but sometimes while doing problem on SPOJ. i noticed when i have execution time of 2 sec (for example), many good coders (Respected) have brought down their execution time to 0.5 sec around .
Here is what i have done for my optimized prime sieve.
Optimization i have done-
1. running main iteration loop to only square root of Limit.
2. avoid for even numbers.
3. not checking for multiple of 2 and 3
4. Prime numbers are of form 6k+1 or 6k+5.
5. in inner loop of j, insted of j+=i, i did j+=2*i. because i*i(as i will be odd for sure, i haven't run this loop for "2") will be odd for sure. so i*i+i will be odd for sure. so skip it by j+=2*i
Since even numbers and multiple of 3 are never marked. so they will never be checked while collecting all primes
#define lim 10000009
vector<bool> isprime(lim,1);
void sieve()
{
int i,j,t,v,sq;
isprime[1]=isprime[0]=0;
sq=sqrt(lim);
for(i=5,t=2;i<=sq; )
{
if(isprime[i])
{
for(j=i*i;j<lim;j+=2*i)
isprime[j]=0; // 0 means composite- not prime , 1 means prime
}
i+=t;
t=6-t;
}
}
Can i improve this more ??? Please help
I know two ways to improve this:
Your implementation have small constant, but still work in O(nloglogn). It's possible to do it in O(n).
Your implementation uses O(n) of memory. It's possible to use only O(
) of memory.
UPD: Also you may try to change
vector<bool>(lim)
tobitset<lim>
. And if problem is "find number of primes from 1 to n", it's solvable in O(n2 / 3)can you enlightened me for the way to do so ??
About n2 / 3: wiki
About O(n): code
About O(
): code
Thanks for the link!! memory management was wonderful , thanks again !!
in sqrt(n) code, you can initialize pos with i * i. sqrt(n) memory is very good optimization because of processor's cache.
you mean regarding that 3MB cache L2 . ?? . i never know it affects that. thanks for giving this info :)
On my old machine the optimal value for step was 1 << 18, not sqrt(10^9).
no i meant on when you said "sqrt(n) memory is very good optimization because of processor's cache." ??
Thanks for method with O(n2 / 3). What is proof that count of subsets of different primes (less or equal
) with their product small or equal n is O(n2 / 3)?
Φ(N, d) — amount of numbers from 1 to N with all prime divisors greater than d.
π(N) = Φ(N,
) + π(
)
Φ(n, d) = Φ(n, d - 1) — Φ(n / d, d)
Let n ≤ N2 / 3 => precalculation
Let N > n > N2 / 3 => n = N / x, where x ≤ N1 / 3 and d ≤ N1 / 3. There are only O(N2 / 3) such pairs <x, d>. So there are only O(N2 / 3) non-trivial states.
Last case: N = n. There are
such states.
Both
vector<bool>
andbitset
are slow, if memory is not a constraint, it is better to usevector<char>
.yes. i am considering this specific change too !!
There is an easy coding O(n) algorithm. I don't know how it is called in English, so here the code comes.
isp[x] stands for whether x is a prime, fac[x] is the smallest prime factor of x. UPD[http://www.csie.ntnu.edu.tw//Prime.html#a2]a web page about this algorithm in Chinese, you can use google translate to understand it.(http://www.csie.ntnu.edu.tw/~u91029/Prime.html#a2)