Ordered Radicals
The radical of n, denoted rad(n), is the product of the distinct prime factors of n. For example, rad(504) = 2 x 3 x 7 = 42. By convention, rad(1) = 1. Sort the integers 1 <= n <= 100,000 by the pa...
Problem Statement
This archive keeps the full statement, math, and original media on the page.
The radical of \(n\), \(\operatorname {rad}(n)\), is the product of the distinct prime factors of \(n\). For example, \(504 = 2^3 \times 3^2 \times 7\), so \(\operatorname {rad}(504) = 2 \times 3 \times 7 = 42\).
If we calculate \(\operatorname {rad}(n)\) for \(1 \le n \le 10\), then sort them on \(\operatorname {rad}(n)\), and sorting on \(n\) if the radical values are equal, we get:
| | |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
Let \(E(k)\) be the \(k\)-th element in the sorted \(n\) column; for example, \(E(4) = 8\) and \(E(6) = 9\).
If \(\operatorname {rad}(n)\) is sorted for \(1 \le n \le 100000\), find \(E(10000)\).
Problem 124: Ordered Radicals
Mathematical Development
Definition 1. For a positive integer with prime factorization , the radical is . Equivalently, .
Theorem 1 (Radical and squarefreeness). if and only if is squarefree. For any prime power with , .
Proof. If is squarefree, then . Conversely, if some prime divides with exponent , then . For : the unique prime divisor is , so .
Theorem 2 (Sieve computation of radicals). Initialize for all . For each prime (identified during the sieve), multiply by for every multiple of in . Upon completion, for all .
Proof. Each prime dividing contributes exactly one factor of to , since is multiplied in when processing multiples of , and this happens exactly once per prime (the sieve only processes primes, not composite numbers). No prime contributes to , since is not a multiple of . Primes are identified as those satisfying when is first reached (i.e., has no prime factor smaller than itself).
Lemma 1 (Total order). The lexicographic order on pairs is a total order on : for distinct , either (ordered by radical) or and the tiebreaker is decisive.
Proof. Immediate from the definition of lexicographic order and the uniqueness of .
Editorial
The expensive part is not the final selection but computing all radicals efficiently. A sieve handles that cleanly: each time a prime is discovered, multiply into the radical of every multiple of . Because each prime contributes only once to each number, the resulting array is exactly for every .
After that, the rest is a pure ordering problem. Form the pairs , sort them lexicographically, and read off the entry in position 10000. The secondary key automatically resolves ties between equal radicals.
Pseudocode
Initialize every radical value to 1.
Sweep through the integers from 2 up to 100000.
Whenever the current integer is still marked with radical 1, treat it as prime and multiply it into the radical of each of its multiples.
Build the list of pairs (rad(n), n) for all n in the range.
Sort that list in lexicographic order and return the n-value in position 10000.
Complexity Analysis
- Time: for the sieve (each prime visits multiples; summing over primes gives by Mertens’ theorem). Sorting requires . Total: .
- Space: for the radical array and sorted pairs.
Answer
Code
Each problem page includes the exact C++ and Python source files from the local archive.
#include <bits/stdc++.h>
using namespace std;
int main() {
const int N = 100000;
const int K = 10000;
vector<int> rad(N + 1, 1);
for (int i = 2; i <= N; i++) {
if (rad[i] == 1) { // i is prime
for (int j = i; j <= N; j += i)
rad[j] *= i;
}
}
vector<pair<int, int>> v;
v.reserve(N);
for (int i = 1; i <= N; i++)
v.push_back({rad[i], i});
sort(v.begin(), v.end());
cout << v[K - 1].second << endl;
return 0;
}
"""
Problem 124: Ordered Radicals
Compute rad(n) for 1 <= n <= 100000 via sieve, sort by (rad(n), n),
return E(10000).
"""
def solve():
N = 100000
K = 10000
rad = [1] * (N + 1)
for i in range(2, N + 1):
if rad[i] == 1: # i is prime
for j in range(i, N + 1, i):
rad[j] *= i
sorted_list = sorted(range(1, N + 1), key=lambda n: (rad[n], n))
print(sorted_list[K - 1])
solve()