Maths For Competitive Programming: Primes

As a competitive programmer, it is important to have a strong foundation in mathematics, as it can be a useful tool in solving problems efficiently. In this blog post, we will focus on one particular area of math that is particularly useful in competitive programming: prime numbers.

What are prime numbers?

A prime number is a positive integer greater than 1 that has no positive integer divisors other than 1 and itself. For example, the first few prime numbers are 2, 3, 5, 7, 11, and 13. Prime numbers are often of interest in computer science because they can be used to test the efficiency of algorithms.

How to check if a number is a prime?

One simple method for determining whether a number is prime is to check if it is divisible by any number other than 1 and itself. However, this method can be inefficient for larger numbers, as it requires checking every number up to the target number. We can also save up time by checking till the square root of the target number. We can also eliminate all even numbers except 2 since 2 is the only even prime.

A more efficient method is the Sieve of Eratosthenes. The Sieve of Eratosthenes is an algorithm for finding all the prime numbers up to a given limit. It works by first creating a list of all the integers from 2 to the given limit. It considers all the numbers as prime numbers. It then iterates through the list, marking each prime number's multiples as composite (not prime). In the end, the remaining unmarked numbers are all prime numbers up to the given limit.

For example: All the prime numbers less than 10

2 3 4 5 6 7 8 9

We consider all of them to be prime.

Now we cross all the multiples of 2 as it is our first prime number.

2 3 5 7 9

We now cross all the multiples of 3

2 3 5 7

All the remaining numbers are prime numbers.

The code for the algorithm in cpp:

#include <bits/stdc++.h>
using namespace std;

const int N = 1000000;

// Create a boolean array "prime[0..n]" and
// initialize all entries it as true. A value
// in prime[i] will finally be false if i is
// Not a prime, else true.
bool prime[N+1];

void sieve()
{

    for (int p=2; p*p<=N; p++)
    {
        // If prime[p] is not changed, then
        // it is a prime
        if (prime[p] == true)
        {
            // Update all multiples of p. We iterate through the list with p intervals.
            for (int i=p*2; i<=N; i += p)
                prime[i] = false;
        }
    }
}

// Driver code
int main()
{
    sieve();

    // Print all prime numbers
    for (int p=2; p<=N; p++)
       if (prime[p])
          cout << p << " ";

    return 0;
}

This implementation of the Sieve of Eratosthenes has a time complexity of O(n log log n), making it efficient for finding prime numbers up to a given limit.