Perfect Power Detection
A perfect power is an integer of the form a^b where a >= 1 and b >= 2. Find the number of distinct perfect powers in {1, 2,..., 10^18}.
Problem Statement
This archive keeps the full statement, math, and original media on the page.
Two players X and O play a game with
Starting with X, they make moves in turn. At X's turn, X draws an "X" symbol; at O's turn, O draws an "O" symbol.
The symbol must be drawn in one blank square with either red or blue pen, subject to the following restrictions:
- two symbols in adjacent squares on one strip must be different symbols and must have different colour;
- if there is at least one blank strip, then one must draw on a blank strip.
Whoever does not have a valid move loses the game.
Let
For example,
Find
Problem 976: Perfect Power Detection
Mathematical Foundation
Definition 1. Let . We seek for .
Theorem 1 (Reduction to Prime Exponents). Every perfect power with can be written as for some prime and integer .
Proof. Write where is a prime factor of . Then with .
Theorem 2 (Inclusion-Exclusion Formula). Let , so . Then:
where is the set of relevant prime exponents.
Proof. By inclusion-exclusion on the sets . A number in (with distinct primes) is an -th power, i.e., a -th power (since the are distinct primes). Thus . The union has no contribution from primes since and is already counted.
Lemma 1 (Exponent Bound). For , the relevant primes are , since .
Proof. If is prime, then , so contributes only , which is already in every .
Lemma 2 (Truncation of Inclusion-Exclusion). For , any subset with satisfies . Thus only subsets with product contribute nontrivially.
Proof. If , then , so . These terms contribute a net correction that must be carefully tracked (adding/subtracting 1).
Editorial
Count the number of distinct perfect powers a^b <= 10^18, where a >= 1 and b >= 2. A perfect power is an integer that can be expressed as a^b for integers a >= 1, b >= 2. Numbers like 64 = 2^6 = 4^3 = 8^2 should only be counted once. We relevant prime exponents. We then iterate over all non-empty subsets of primes where product <= log2(N). Finally, use inclusion-exclusion.
Pseudocode
Relevant prime exponents
Iterate over all non-empty subsets of primes where product <= log2(N)
Use inclusion-exclusion
for each non-empty subset S of primes
floor(N^{1/e}) = 1, handle separately
else
Handle the subsets with large products (contribute +/- 1)
by careful enumeration
Note: N^{1/e} must be computed with care for large N
Use integer Newton's method: find largest a such that a^e <= N
Adjust: check a^e <= N < (a+1)^e
Complexity Analysis
- Time: subsets to enumerate, but heavy truncation (most subsets have product and are trivial) reduces this drastically. The dominant cost is only as a value, not a loop. Each
IntegerRootcall is Newton iterations with -bit arithmetic. In practice: ) with , giving subsets, each with constant-time root computation. Total: . - Space: .
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() {
// For 10^18 we need careful computation
// Count distinct a^b with a>=1, b>=2, a^b <= 10^18
// Use set of (base reduced to primitive form)
long long N = 1000000000000000000LL;
set<long long> seen;
seen.insert(1);
for (int b = 2; b <= 60; b++) {
long long a = 2;
while (true) {
// Compute a^b, watch for overflow
long long val = 1;
bool overflow = false;
for (int i = 0; i < b; i++) {
if (val > N / a) { overflow = true; break; }
val *= a;
}
if (overflow || val > N) break;
seen.insert(val);
a++;
}
}
cout << (long long)seen.size() << endl;
return 0;
}
"""
Problem 976: Perfect Power Detection
Count the number of distinct perfect powers a^b <= 10^18, where a >= 1 and b >= 2.
A perfect power is an integer that can be expressed as a^b for integers a >= 1, b >= 2.
Numbers like 64 = 2^6 = 4^3 = 8^2 should only be counted once.
Key results:
- Enumerate all a^b for b = 2..60 (since 2^60 > 10^18), a = 2..iroot(N,b)
- Use a set to deduplicate (e.g., 64 appears as 2^6, 4^3, 8^2)
- Include 1 = 1^b for any b
- answer = number of distinct perfect powers <= 10^18
Methods:
1. iroot — integer b-th root via Newton + binary search
2. count_perfect_powers_brute — brute force enumeration with dedup set
3. count_by_exponent — count of b-th powers for each exponent b
4. perfect_power_density — fraction of integers <= N that are perfect powers
"""
from collections import Counter
def iroot(n, b):
"""Compute floor(n^(1/b)) exactly."""
if n <= 0:
return 0
if b == 1:
return n
# Initial guess from floating point
x = int(round(n ** (1.0 / b)))
# Check neighborhood
for dx in range(-3, 4):
y = x + dx
if y >= 1 and y ** b <= n and (y + 1) ** b > n:
return y
# Fallback: binary search
lo, hi = 1, int(n ** (1.0 / b)) + 2
while lo < hi:
mid = (lo + hi + 1) // 2
if mid ** b <= n:
lo = mid
else:
hi = mid - 1
return lo
def count_perfect_powers_brute(N, max_exp=60):
"""Enumerate all a^b <= N for a>=2, b>=2..max_exp. Return deduplicated set."""
seen = set()
for b in range(2, max_exp + 1):
r = iroot(N, b)
if r < 2:
break
for a in range(2, r + 1):
v = a ** b
if v <= N:
seen.add(v)
seen.add(1) # 1^b for any b
return seen
def count_by_exponent(N, max_exp=60):
"""For each b, how many distinct b-th powers a^b <= N (a >= 2)."""
exponents = []
counts = []
for b in range(2, max_exp + 1):
r = iroot(N, b)
if r < 2:
break
exponents.append(b)
counts.append(r - 1) # a = 2..r
return exponents, counts
def perfect_power_density(max_exp_scale=12):
"""Count perfect powers <= 10^k for k=1..max_exp_scale."""
ks = []
counts = []
densities = []
for k in range(1, max_exp_scale + 1):
Nk = 10 ** k
pp = count_perfect_powers_brute(Nk, max_exp=60)
ks.append(k)
counts.append(len(pp))
densities.append(len(pp) / Nk)
return ks, counts, densities
# Verification
# Perfect powers <= 100: 1,4,8,9,16,25,27,32,36,49,64,81,100 = 13
pp_100 = count_perfect_powers_brute(100)
assert len(pp_100) == 13, f"Expected 13 perfect powers <= 100, got {len(pp_100)}"
assert 64 in pp_100 # 2^6 = 4^3 = 8^2
assert 27 in pp_100 # 3^3
# iroot checks
assert iroot(1000000, 2) == 1000
assert iroot(1000000, 3) == 100
assert iroot(1024, 10) == 2
# Main computation
N = 10 ** 18
seen = count_perfect_powers_brute(N)
answer = len(seen)
print(answer)
# Visualization — 4-panel figure