Skip to main content
๐Ÿ“œ WAYPOINT LESSON

Divisors and Primes in O(sqrt n)

โญ beginnerโณ 13 min read๐Ÿ“ Lesson 32 of 281

Divisors come in pairs; primes are just the absence of them.

Divisor pairs

If d divides n, then n/d also divides n. One of the pair is at most sqrt(n) โ€” so enumerate the small partner only:

vector<long long> divisors(long long n) {
    vector<long long> small, big;
    for (long long d = 1; d * d <= n; ++d)
        if (n % d == 0) {
            small.push_back(d);
            if (d != n / d) big.push_back(n / d);
        }
    // merge small (ascending) with big (reversed): sorted divisors
    return small;
}

Loop condition d * d <= n (not d <= sqrt(n)) avoids floating point entirely. The d != n/d check keeps perfect squares from listing sqrt(n) twice.

Primality

A prime has no divisor pair except (1, n):

bool isPrime(long long n) {
    if (n < 2) return false;
    for (long long d = 2; d * d <= n; ++d)
        if (n % d == 0) return false;
    return true;
}

O(sqrt n). n = 10^12 needs 10^6 iterations โ€” fine. Trial division by every number up to n is O(n) and fails the same test. Do not "optimize" by checking only odd d and forgetting 2.

Counting divisors without listing

Iterate the same pairs and add 1 (or 2, or 1 for the square root):

long long countDivisors(long long n) {
    long long cnt = 0;
    for (long long d = 1; d * d <= n; ++d)
        if (n % d == 0) cnt += (d == n / d) ? 1 : 2;
    return cnt;
}

Digit sum

long long digitSum(long long n) {
    long long s = 0;
    while (n) { s += n % 10; n /= 10; }
    return s;
}

Note: n % 10 and n /= 10 work on the absolute value โ€” for negatives, take abs first (C++ division truncates toward zero, so the sign survives in n until n becomes 0; the digits come out positive anyway, but the cleanest is n = llabs(n) at the top).

โšก Now practice

Ready to Code
Number Theory Problem Setgcd/lcm, divisor counting, primality, digit chains, and divisor sums โ€” all O(sqrt n) drills.
5 challenges ยท ยท ~45 min