abc-hits
The radical of n, rad(n), is the product of the distinct prime factors of n. A triple (a, b, c) is an abc-hit if: 1. gcd(a, b) = 1 2. a < b 3. a + b = c 4. rad(abc) < c Find sum c for all abc-hits...
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 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$.
We shall define the triplet of positive integers $(a, b, c)$ to be an abc-hit if:
$\gcd(a, b) = \gcd(a, c) = \gcd(b, c) = 1$
$a < b$
$a + b = c$
$\operatorname{rad}(abc) < c$
For example, $(5, 27, 32)$ is an abc-hit, because:
$\gcd(5, 27) = \gcd(5, 32) = \gcd(27, 32) = 1$
$5 < 27$
$5 + 27 = 32$
$\operatorname{4320}{4320} = 30 < 32$
It turns out that abc-hits are quite rare and there are only thirty-one abc-hits for $c < 1000$, with $\sum c = 12523$.
Find $\displaystyle \sum c$ for $c < 120000$.
Problem 127: abc-hits
Mathematical Development
Theorem 1 (Pairwise coprimality). If and , then , , are pairwise coprime.
Proof. Suppose a prime divides both and . Then , contradicting . By symmetry (swapping and ), as well.
Theorem 2 (Radical factorization for coprime triples). If , , are pairwise coprime, then .
Proof. Since , , share no common prime factor, the set of primes dividing is the disjoint union of primes dividing , , and respectively. Therefore .
Lemma 1 (Reformulated condition). The abc-hit condition is equivalent to .
Proof. By Theorem 2, . The inequality divides both sides by .
Lemma 2 (Coprimality via radicals). For positive integers and , if and only if .
Proof. : If a prime divides both and , then and , contradicting . : If , then and , contradicting .
Theorem 3 (Search strategy). For each , sorting candidates by in ascending order allows early termination: once , no further can satisfy the condition (since ).
Proof. If , then for all . Thus the condition fails, and all subsequent (with equal or larger radical) also fail.
Editorial
The radical condition is what makes the search manageable. For a fixed , Theorem 2 rewrites as a bound on , so once is known, only values of with sufficiently small radical can possibly work. That suggests computing all radicals first and then iterating candidate values in increasing radical order.
The implementation follows exactly that plan. It sieves the radical array, sorts the integers by radical, and for each scans only as far as the threshold allows. For every surviving , it recovers , enforces , checks the radical inequality, and uses the coprimality test to confirm an abc-hit before adding to the total.
Pseudocode
Use a sieve to compute rad(n) for every n below the limit.
Create the list of candidate a-values sorted by increasing rad(a).
For each c from 3 up to 119999:
Compute the threshold c / rad(c).
Scan the sorted a-values only while rad(a) stays below that threshold.
For each such a:
Set b = c - a.
Skip the pair unless a < b.
Skip it unless rad(a) rad(b) is still below the threshold.
Skip it unless the coprimality condition holds.
Otherwise record an abc-hit and add c to the answer.
Return the accumulated sum.
Complexity Analysis
- Time: for the sieve. for sorting. The main search loop: for each , the inner loop terminates early due to the radical threshold. Empirically, the total work across all is .
- Space: for the radical array and sorted index.
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 = 120000;
vector<int> rad(N, 1);
// Sieve for radicals
for (int p = 2; p < N; p++) {
if (rad[p] == 1) { // p is prime
for (int m = p; m < N; m += p) {
rad[m] *= p;
}
}
}
// Sort indices 1..N-1 by radical (skip 0)
vector<int> sorted_by_rad;
sorted_by_rad.reserve(N - 1);
for (int i = 1; i < N; i++) sorted_by_rad.push_back(i);
sort(sorted_by_rad.begin(), sorted_by_rad.end(),
[&](int x, int y) { return rad[x] < rad[y]; });
long long total = 0;
for (int c = 3; c < N; c++) {
long long threshold = (long long)c / rad[c];
if (threshold <= 1) continue;
for (int i = 0; i < (int)sorted_by_rad.size(); i++) {
int a = sorted_by_rad[i];
if (rad[a] >= threshold) break;
if (a >= c) continue;
int b = c - a;
if (a >= b) continue;
if ((long long)rad[a] * rad[b] >= threshold) continue;
if (__gcd(rad[a], rad[b]) != 1) continue;
total += c;
}
}
cout << total << endl;
return 0;
}
"""
Problem 127: abc-hits
Find the sum of c for all abc-hits below 120000.
An abc-hit: gcd(a,b)=1, a<b, a+b=c, rad(abc) < c.
"""
from math import gcd
def solve():
N = 120000
rad = [1] * N
# Sieve for radicals
for p in range(2, N):
if rad[p] == 1: # p is prime
for m in range(p, N, p):
rad[m] *= p
# Sort indices 1..N-1 by their radical (skip 0)
sorted_by_rad = sorted(range(1, N), key=lambda x: rad[x])
total = 0
for c in range(3, N):
threshold = c // rad[c]
if threshold <= 1:
continue
for a in sorted_by_rad:
if rad[a] >= threshold:
break
if a >= c:
continue
b = c - a
if a >= b:
continue
if rad[a] * rad[b] >= threshold:
continue
if gcd(rad[a], rad[b]) != 1:
continue
total += c
return total
if __name__ == '__main__':
answer = solve()
print(answer)