All Euler problems
Project Euler

Square Root Smooth Numbers

A positive integer n is called square root smooth if all of its prime factors are strictly less than sqrt(n). Including the number 1, there are 29 square root smooth numbers not exceeding 100. How...

Source sync Apr 19, 2026
Problem #0668
Level Level 13
Solved By 1,237
Languages C++, Python
Answer 2811077773
Length 640 words
number_theorylinear_algebrabrute_force

Problem Statement

This archive keeps the full statement, math, and original media on the page.

A positive integer is called square root smooth if all of its prime factors are strictly less than its square root.

Including the number \(1\), there are \(29\) square root smooth numbers not exceeding \(100\).

How many square root smooth numbers are there not exceeding \(10\,000\,000\,000\)?

Problem 668: Square Root Smooth Numbers

Mathematical Analysis

Definition Formalization

A number n>1n > 1 is square root smooth if its largest prime factor P+(n)<nP^+(n) < \sqrt{n}, i.e., P+(n)2<nP^+(n)^2 < n. By convention, n=1n = 1 is square root smooth (it has no prime factors).

Key Observation

The complementary set (numbers that are NOT square root smooth, excluding 1) consists of numbers nNn \le N where nn has a prime factor pnp \ge \sqrt{n}. Any such nn can be written as n=pmn = p \cdot m where pp is prime, pnp \ge \sqrt{n}, and m=n/pn<pm = n/p \le \sqrt{n} < p. Since m<pm < p and pp is the largest prime factor, mm must be a positive integer with all prime factors <p< p.

Counting Strategy

Total square root smooth numbers =N{nN:n>1 and n is not square root smooth}= N - |\{n \le N : n > 1 \text{ and } n \text{ is not square root smooth}\}|.

Equivalently, let f(N)f(N) count square root smooth numbers N\le N:

f(N)=NpNp prime(π ⁣(Np)π(p)+1)[adjusted]f(N) = N - \sum_{\substack{p \le N \\ p \text{ prime}}} \left(\pi\!\left(\frac{N}{p}\right) - \pi(p) + 1\right) \cdot [\text{adjusted}]

A cleaner approach: count numbers NOT square root smooth. Each such nn has a unique representation n=pmn = p \cdot m where p=P+(n)p = P^+(n) (largest prime factor) and 1mN/p1 \le m \le N/p, with all prime factors of mm less than pp.

So the count of non-square-root-smooth nNn \le N (excluding 1) is:

p primep2NΨ(N/p,p)+π(N)π(N)\sum_{\substack{p \text{ prime} \\ p^2 \le N}} \Psi(N/p, p) + \pi(N) - \pi(\lfloor\sqrt{N}\rfloor)

Wait — let’s be more careful. A number n>1n > 1 is NOT square root smooth iff P+(n)nP^+(n) \ge \sqrt{n}, i.e., P+(n)2nP^+(n)^2 \ge n.

We can split into two cases:

  1. n=pn = p is prime (m=1m = 1): there are π(N)\pi(N) such numbers.
  2. n=pmn = p \cdot m with m>1m > 1, p=P+(n)p = P^+(n), and p2np^2 \ge n, so pn>mpp \ge \sqrt{n} > \sqrt{m \cdot p}, giving p>mp > m. All prime factors of mm are <p< p, and mpNm \cdot p \le N.

For case 2, for each prime pp, mm ranges over integers 2mN/p2 \le m \le N/p with m<pm < p and all prime factors of mm less than pp. Since m<pm < p and pp is prime, the condition “all prime factors of mm less than pp” is automatic. So the count for case 2 is:

p primepN/2(min(p1,N/p)1)\sum_{\substack{p \text{ prime} \\ p \le N/2}} (\min(p-1, \lfloor N/p \rfloor) - 1)

Thus:

f(N)=1+Nπ(N)p prime2pN/2(min(p1,N/p)1)f(N) = 1 + N - \pi(N) - \sum_{\substack{p \text{ prime} \\ 2 \le p \le N/2}} (\min(p-1, \lfloor N/p \rfloor) - 1)

Simplify: For pNp \le \sqrt{N}: min(p1,N/p)=p1\min(p-1, N/p) = p-1, contributing p2p - 2. For N<pN/2\sqrt{N} < p \le N/2: min(p1,N/p)=N/p\min(p-1, N/p) = \lfloor N/p \rfloor, contributing N/p1\lfloor N/p \rfloor - 1.

f(N)=1+Nπ(N)pN(p2)N<pN/2(N/p1)f(N) = 1 + N - \pi(N) - \sum_{\substack{p \le \sqrt{N}}} (p - 2) - \sum_{\substack{\sqrt{N} < p \le N/2}} (\lfloor N/p \rfloor - 1)

Editorial

A positive integer n is square root smooth if all prime factors < sqrt(n). Count such n <= N = 10^10 (including 1). n is NOT square root smooth iff it has a prime factor p >= sqrt(n). We count the complement. For each n > 1, let p = P+(n) be largest prime factor. n is not smooth iff p^2 >= n. Write n = p * m where m = n/p. Then m < p (from p^2 >= n = pm => p > m, actually p >= m, and if p = m then n = p^2, P+(n) = p = sqrt(n), not strictly less). Case A: m = 1, i.e., n = p is prime. Count = pi(N). Case B: m >= 2, m < p, all prime factors of m < p (auto since m < p). For each prime p: m from 2 to min(p-1, N//p). Number of valid m = min(p-1, N//p) - 1. Answer = 1 + N - pi(N) - sum over primes p of (min(p-1, N//p) - 1) where the sum is over primes 2 <= p <= N//2. But wait: for p = 2, min(p-1, N//p) - 1 = min(1, 5*10^9) - 1 = 0. That’s correct since m must be >= 2 and < 2, impossible. For p = 3: min(2, N//3) - 1 = 1. So m = 2, n = 6. Check: P+(6) = 3 >= sqrt(6) ~ 2.45. Yes. Let me verify with N = 100, answer should be 100 - (100 - 29) = 29. We use a prime sieve up to N=105\sqrt{N} = 10^5 to get small primes. We then iterate over primes N<pN/2\sqrt{N} < p \le N/2, we need to compute (N/p1)\sum (\lfloor N/p \rfloor - 1). Group by values of N/p\lfloor N/p \rfloor and use the Lucy_Hedgehog method (or segmented sieve) for prime counting. Finally, use the Meissel-Lehmer method to compute π(N)\pi(N) and related prime counting sums.

Pseudocode

Use a prime sieve up to $\sqrt{N} = 10^5$ to get small primes
For primes $p \le \sqrt{N}$, sum $(p - 2)$
For primes $\sqrt{N} < p \le N/2$, we need to compute $\sum (\lfloor N/p \rfloor - 1)$. Group by values of $\lfloor N/p \rfloor$ and use the Lucy_Hedgehog method (or segmented sieve) for prime counting
Use the Meissel-Lehmer method to compute $\pi(N)$ and related prime counting sums

Correctness

Theorem. The method described above computes exactly the quantity requested in the problem statement.

Proof. The preceding analysis identifies the admissible objects and derives the formula, recurrence, or exhaustive search carried out by the algorithm. The computation evaluates exactly that specification, so every valid contribution is included once and no invalid contribution is counted. Therefore the returned value is the required answer. \square

Complexity Analysis

  • Time: O(N2/3)O(N^{2/3}) using the Meissel-Lehmer approach
  • Space: O(N1/2)O(N^{1/2})

Answer

2811077773\boxed{2811077773}

Code

Each problem page includes the exact C++ and Python source files from the local archive.

C++ project_euler/problem_668/solution.cpp
#include <bits/stdc++.h>
using namespace std;

/*
 * Problem 668: Square Root Smooth Numbers
 *
 * n is square root smooth if all prime factors of n are STRICTLY less than sqrt(n).
 * Count f(N) = |{n <= N : n is square root smooth}|.
 *
 * n > 1 is NOT smooth iff P+(n) >= sqrt(n), i.e., P+(n)^2 >= n.
 *
 * Non-smooth numbers:
 * (A) Primes: pi(N) numbers
 * (B) n = p^2 where p prime, p^2 <= N: pi(sqrtN) numbers (P+(p^2)=p=sqrt(n))
 * (C) n = p*m, p = P+(n), 2 <= m <= p-1, m*p <= N, all prime factors of m < p
 *     (automatic since m < p). For each prime p: min(p-1, N/p) - 1 valid m values.
 *
 * f(N) = 1 + N - pi(N) - pi(sqrtN) - sum_{p prime, p<=N/2} max(0, min(p-1, N/p) - 1)
 */

typedef long long ll;

int main(){
    ll N = 10000000000LL;
    ll sqrtN = 100000LL;

    int sN = (int)sqrtN;
    vector<bool> is_prime(sN + 1, true);
    is_prime[0] = is_prime[1] = false;
    for(int i = 2; (ll)i * i <= sN; i++){
        if(is_prime[i]){
            for(int j = i*i; j <= sN; j += i)
                is_prime[j] = false;
        }
    }

    // Lucy_Hedgehog prime counting
    vector<ll> small(sN + 2, 0), large(sN + 2, 0);
    for(int v = 0; v <= sN; v++) small[v] = max(0, v - 1);
    for(int k = 1; k <= sN; k++) large[k] = N / k - 1;

    for(int p = 2; p <= sN; p++){
        if(!is_prime[p]) continue;
        ll pp = (ll)p * p;
        ll pcnt = small[p - 1];

        for(int k = 1; k <= sN && (ll)k * pp <= N; k++){
            ll val = N / ((ll)k * p);
            ll sub;
            if(val <= sN)
                sub = small[(int)val];
            else
                sub = large[(int)((ll)k * p)];
            large[k] -= sub - pcnt;
        }

        for(int v = sN; v >= pp; v--){
            small[v] -= small[v / p] - pcnt;
        }
    }

    auto getPi = [&](ll x) -> ll {
        if(x <= 0) return 0;
        if(x <= sN) return small[(int)x];
        return large[(int)(N / x)];
    };

    ll piN = large[1];
    ll piSqrtN = small[sN]; // pi(sqrtN)

    // Part 1: primes p <= sqrtN, contribution = p - 2 (for p >= 3)
    ll sum1 = 0;
    for(int p = 3; p <= sN; p++){
        if(is_prime[p]) sum1 += p - 2;
    }

    // Part 2: primes sqrtN < p <= N/2, contribution = N//p - 1
    ll maxq = N / (sqrtN + 1);
    ll sum2 = 0;
    for(ll q = 2; q <= maxq; q++){
        ll phi = N / q;
        ll plo = N / (q + 1);
        if(phi <= sqrtN) continue;
        if(plo < sqrtN) plo = sqrtN;
        ll cnt = getPi(phi) - getPi(plo);
        if(cnt > 0)
            sum2 += (q - 1) * cnt;
    }

    ll answer = 1 + N - piN - piSqrtN - sum1 - sum2;
    cout << answer << endl;

    return 0;
}