Find the number of prime numbers in a given range

I found the following code for finding primes in a given range. But I’m unable to understand the function of Set notprime. Can anyone please explain how this program works. Is it an algo I’m unaware of?

#include <iostream>
#include <cmath>
#include <vector>
#include <set>
using namespace std;

int main() {
    vector<int> primes;
    primes.push_back(2);

    for (int i = 3; i <= 32000; i+=2) {
            bool isprime = true;
            int cap = sqrt(i) + 1;

            vector<int>::iterator p;
            for (p = primes.begin(); p != primes.end(); p++) {
                if (*p >= cap) break;
                if (i % *p == 0) {
                    isprime = false;
                    break;
                }
            }
            if (isprime) primes.push_back(i);
    }

    int T,N,M;

    cin >> T;

    for (int t = 0; t < T; t++) {
            if (t) cout << endl;

            cin >> M >> N;
            if (M < 2) M = 2;

            int cap = sqrt(N) + 1;

            set<int> notprime;
            notprime.clear();

            vector<int>::iterator p;
            for (p = primes.begin(); p != primes.end(); p++) {

                    if (*p >= cap) break;
                    int start;

                if (*p >= M) start = (*p)*2;
                else start = M + ((*p - M % *p) % *p);

                for (int j = start; j <= N; j += *p) {
                        notprime.insert(j);
                }
            }

            for (int i = M; i <= N; i++) {
                if (notprime.count(i) == 0) {
                        cout << i << endl;
                }
            }

    }
    return 0;
}

He is only printing not_prime in given range and saving the notprimes in the set.
notPrimes are multiples of prime numbers.

Becuase for two (prime or non-prime) numbers p1 and p2, p1 * p2 = p2 * p1, he kept set to avoid duplication.

For example to print between 4-8, we would get 6 twice.

@dakota:

The solution u posted maintains the non prime numbers(multiples of prime numbers), at the end he is checking the frequency of each number in the interval M to N.

Since the prime numbers are excluded from the notprime set, their frequency is 0. Therefore he print it as a prime.

//