1

Can anyone please tell me how this is working in O(n).

http://www.geeksforgeeks.org/sieve-eratosthenes-0n-time-complexity/

void manipulated_seive(int N)
{
    // 0 and 1 are not prime
    isprime[0] = isprime[1] = false ;

    // Fill rest of the entries
    for (long long int i=2; i<N ; i++)
    {
        // If isPrime[i] == True then i is
        // prime number
        if (isprime[i])
        {
            // put i into prime[] vector
            prime.push_back(i);

            // A prime number is its own smallest
            // prime factor
            SPF[i] = i;
        }

        // Remove all multiples of  i*prime[j] which are
        // not prime by making isPrime[i*prime[j]] = false
        // and put smallest prime factor of i*Prime[j] as prime[j]
        // [ for exp :let  i = 5 , j = 0 , prime[j] = 2 [ i*prime[j] = 10 ]
        // so smallest prime factor of '10' is '2' that is prime[j] ]
        // this loop run only one time for number which are not prime
        for (long long int j=0;
             j < (int)prime.size() &&
             i*prime[j] < N && prime[j] <= SPF[i];
             j++)
        {
            isprime[i*prime[j]]=false;

            // put smallest prime factor of i*prime[j]
            SPF[i*prime[j]] = prime[j] ;
        }
    }
}

I think the outer loop will run O(n) time and inner loop will run O(number of primes less than N) in case of prime numbers and O(1) in case of composite. But overall is should be O(n) * O(number of primes less than n). Am i missing something?

Thanks in advance.

Will Ness
  • 70,110
  • 9
  • 98
  • 181
rittik
  • 63
  • 5
  • I think that it is dishonest to call this `O(N)`. The constants on multiplication and storing integers are worse than on bit twiddling with the usual sieve. By the time the `log(log(N))` factor is able to matter, it will matter rather more that multiplication of arbitrary size integers is far from constant time, and your constants are *still* worse. – btilly Jun 07 '17 at 22:18
  • 2
    endless indirections & multiplications, arrays indexed by `long long int`, inherently non-segmentable algorithm... this is guaranteed to perform abysmally. As soon as N outgrows your cache size, it'll slow down immensely, so you'd be testing up to what, 10000 primes at the most, if that? unlikely the bigint multiplications will have any chance to even come into play (@btilly). this is [Gries & Misra](https://www.cs.utexas.edu/users/misra/scannedPdf.dir/linearSieve.pdf), BTW. -- the key to SoE's efficiency is its supposed redundancy. any attempt at removing it incurs too much overhead. – Will Ness Jun 07 '17 at 23:57

1 Answers1

2

The key idea is that each integer between 2 and n is encountered exactly once in the SPF calculation, thus the total number of iterations of the innermost loop is O(n).

The innermost loop fills the SPF array which indicates the smallest prime factor, for each integer between 2 and n.

Indeed, to compute the SPF array, each integer k between 2 and n is represented as k = i*prime[j], where prime[j] is a prime number below all prime factors of i (this is ensured by the prime[j] <= SPF[i] condition which would break the loop otherwise). This means that prime[j] is the smallest prime factor of k. But this representation is unique for each k (i.e. the same k won't be encountered once again, as another k = i2 * prime[j2] factorization, because if prime[j2] is not equal to prime[j] then one of them would not be the smallest prime factor of k). Thus each number k between 2 and n appears exactly once as the product i*prime[j], computed in the innermost loop.

danbanica
  • 3,018
  • 9
  • 22