Strong Achilles Numbers
A positive integer n is powerful if for every prime p dividing n, we have p^2 | n. An Achilles number is a powerful number that is not a perfect power (i.e., it cannot be expressed as m^k for integ...
Problem Statement
This archive keeps the full statement, math, and original media on the page.
A positive integer \(n\) is powerful if \(p^2\) is a divisor of \(n\) for every prime factor \(p\) in \(n\).
A positive integer \(n\) is a perfect power if \(n\) can be expressed as a power of another positive integer.
A positive integer \(n\) is an Achilles number if \(n\) if powerful but not a perfect power. For example, \(864\) and \(1800\) are Achilles number: \(864 = 2^5 \cdot 3^3\) and \(1800 = 2^3 \cdot 3^2 \cdot 5^2\).
We shall call a positive integer \(S\) a Strong Achilles number if both \(S\) and \(\phi (S)\) are Achilles numbers.
For example, \(846\) is a Strong Achilles number: \(\phi (864) = 288 = 2^5 \cdot 3^2\). However, \(1800\) isn’t a Strong Achilles number because: \(\phi (1800) = 480 = 2^5 \cdot 3^1 \cdot 5^1\).
There are \(7\) Strong Achilles numbers below \(10^4\) and \(656\) below \(10^8\).
How many Strong Achilles numbers are there below \(10^{18}\)?
Problem 302: Strong Achilles Numbers
Mathematical Development
Definition 1. A positive integer is powerful if for every prime , where denotes the -adic valuation.
Theorem 1 (Characterization of powerful numbers). A positive integer is powerful if and only if every exponent in its canonical factorization satisfies . Equivalently, can be written as for some positive integers .
Proof. The first equivalence is immediate from the definition: implies if and only if .
For the second equivalence, suppose every . If is even, write . If is odd, then , so write . Collecting the contributions from the even parts into and the residual factor of 3 into yields . Conversely, if , then whenever .
Lemma 1 (Perfect power criterion). A positive integer with is a perfect power if and only if .
Proof. If , then , so is a -th power. Conversely, if with , then , whence for all , giving .
Lemma 2 (Totient of a powerful number). For with all , we have .
Proof. This follows from the multiplicativity of and the standard formula .
Theorem 2 (Strong Achilles criterion). A positive integer is a Strong Achilles number if and only if all of the following hold:
- (Powerful) for all .
- (Not a perfect power) .
- ( is powerful) In the canonical factorization of , every prime appears with exponent .
- ( is not a perfect power) The gcd of all exponents in the factorization of equals .
Proof. Conditions (1)—(2) are equivalent to being Achilles, by Theorem 1 and Lemma 1. Conditions (3)—(4) state that is Achilles. Together, is Strong Achilles.
Remark. To verify condition (3), one must factor each and merge exponents with the contributions . For primes appearing in the factorization of with , we have , so factoring is efficient.
Editorial
A Strong Achilles number n satisfies: (1) n is powerful (all prime exponents >= 2), (2) n is not a perfect power (gcd of exponents == 1), (3) phi(n) is also Achilles. Enumerate powerful numbers via DFS over prime factorizations, checking all four conditions at each node.
Pseudocode
Set primes <- sieve of primes up to 10^6
Set count <- 0
If product has >= 2 prime factors and gcd_exp == 1 then
If phi_factors is powerful and gcd(phi exponents) == 1 then
Set count <- count + 1
for each prime p = primes[idx], primes[idx+1], ... :
If product * p^2 > N then stop this loop
for e = 2, 3, ... while product * p^e <= N:
Set new_gcd <- gcd(gcd_exp, e)
Set new_phi <- phi_factors merged with factors of p^(e-1)*(p-1)
dfs(idx + 1, product * p^e, new_gcd, new_phi)
dfs(0, 1, 0, {})
Return count
Complexity Analysis
- Time: The number of powerful numbers below is , approximately with (Golomb, 1970). For , this is in the worst case, but the Achilles and Strong Achilles conditions aggressively prune the DFS tree. In practice, the search terminates in manageable time.
- Space: for the prime sieve (primes up to , though we need only primes up to since any prime with exponent satisfies ). Recursion depth is .
Answer
Code
Each problem page includes the exact C++ and Python source files from the local archive.
#include <bits/stdc++.h>
using namespace std;
/*
* Problem 302: Strong Achilles Numbers below 10^18.
*
* Enumerate powerful numbers n < 10^18 via DFS over prime factorizations.
* Check: (1) all exponents >= 2, (2) gcd of exponents = 1 (Achilles),
* (3)-(4) phi(n) is also Achilles.
*/
typedef long long ll;
typedef __int128 lll;
const ll LIMIT = 1000000000000000000LL;
vector<int> primes;
void gen_primes(int lim) {
vector<bool> sieve(lim + 1, false);
for (int i = 2; i <= lim; i++) {
if (!sieve[i]) {
primes.push_back(i);
for (ll j = (ll)i * i; j <= lim; j += i)
sieve[j] = true;
}
}
}
vector<pair<int, int>> factorize(ll n) {
vector<pair<int, int>> res;
for (int p : primes) {
if ((ll)p * p > n) break;
if (n % p == 0) {
int e = 0;
while (n % p == 0) { n /= p; e++; }
res.push_back({p, e});
}
}
if (n > 1) res.push_back({(int)n, 1});
return res;
}
unordered_map<int, vector<pair<int,int>>> pm1_cache;
const vector<pair<int,int>>& get_pm1_fac(int p) {
auto it = pm1_cache.find(p);
if (it != pm1_cache.end()) return it->second;
pm1_cache[p] = factorize(p - 1);
return pm1_cache[p];
}
ll answer = 0;
void dfs(int idx, lll current_n, int num_primes, int gcd_exp,
unordered_map<int, int>& phi_fac) {
if (num_primes >= 2 && gcd_exp == 1) {
bool powerful = true;
int phi_gcd = 0;
for (auto& [p, e] : phi_fac) {
if (e < 2) { powerful = false; break; }
phi_gcd = __gcd(phi_gcd, e);
}
if (powerful && phi_gcd == 1)
answer++;
}
for (int i = idx; i < (int)primes.size(); i++) {
ll p = primes[i];
if (current_n * (lll)p * p > LIMIT) break;
const auto& pm1_fac = get_pm1_fac(p);
lll power = (lll)p * p;
for (int e = 2; current_n * power <= LIMIT; e++) {
int new_gcd = (gcd_exp == 0) ? e : __gcd(gcd_exp, e);
phi_fac[p] += (e - 1);
for (auto& [q, f] : pm1_fac) phi_fac[q] += f;
dfs(i + 1, current_n * power, num_primes + 1, new_gcd, phi_fac);
for (auto& [q, f] : pm1_fac) {
phi_fac[q] -= f;
if (phi_fac[q] == 0) phi_fac.erase(q);
}
phi_fac[p] -= (e - 1);
if (phi_fac[p] == 0) phi_fac.erase(p);
if (power > (lll)LIMIT / p) break;
power *= p;
}
}
}
int main() {
gen_primes(1000000);
unordered_map<int, int> phi_fac;
dfs(0, 1, 0, 0, phi_fac);
printf("%lld\n", answer);
return 0;
}
"""
Problem 302: Strong Achilles Numbers below 10^18.
A Strong Achilles number n satisfies:
(1) n is powerful (all prime exponents >= 2),
(2) n is not a perfect power (gcd of exponents == 1),
(3) phi(n) is also Achilles.
Enumerate powerful numbers via DFS over prime factorizations,
checking all four conditions at each node.
"""
from math import gcd
from functools import reduce
from sympy import factorint, primerange
LIMIT = 10**18
small_primes = list(primerange(2, 10**6 + 1))
def is_achilles(fac):
"""Check if a number with factorization {p: e} is Achilles."""
if not fac:
return False
exps = list(fac.values())
if any(e < 2 for e in exps):
return False
return reduce(gcd, exps) == 1
def phi_factorization(prime_exp_list):
"""Compute the factorization of phi(n) given n = prod p_i^{e_i}."""
phi_fac = {}
for p, e in prime_exp_list:
if e - 1 > 0:
phi_fac[p] = phi_fac.get(p, 0) + (e - 1)
for q, f in factorint(p - 1).items():
phi_fac[q] = phi_fac.get(q, 0) + f
return phi_fac
answer = 0
def dfs(idx, current_n, exponents, gcd_exp):
global answer
if exponents:
if gcd_exp == 1:
phi_fac = phi_factorization(exponents)
if is_achilles(phi_fac):
answer += 1
for i in range(idx, len(small_primes)):
p = small_primes[i]
pp = p * p
if current_n * pp > LIMIT:
break
power = pp
e = 2
while current_n * power <= LIMIT:
new_gcd = e if gcd_exp == 0 else gcd(gcd_exp, e)
exponents.append((p, e))
dfs(i + 1, current_n * power, exponents, new_gcd)
exponents.pop()
if power > LIMIT // p:
break
power *= p
e += 1
dfs(0, 1, [], 0)
print(answer)