Powerful Integers
All values `x^i + y^j <= bound` for non-negative i, j — bounded brute force with a set.
3 min read
hash-set math
Problem#
Given positive integers x, y, bound, return all distinct values of x^i + y^j (for non-negative i, j) that are at most bound.
Examples#
x = 2, y = 3, bound = 10→[2,3,4,5,7,9,10].x = 3, y = 5, bound = 15→[2,4,6,8,10,14].
Constraints#
1 <= x, y <= 100,0 <= bound <= 10^6.
Hints#
Hint
Powers grow fast — only
O(log bound) values of each base fit. Approach#
Enumerate x^i for i = 0..log_x(bound) and similarly y^j. Sum each pair; if <= bound, insert into a set. Edge case: if x == 1, only x^0 = 1 matters (otherwise infinite loop) — same for y.
Solution#
class Solution {public: vector<int> powerfulIntegers(int x, int y, int bound) { unordered_set<int> seen; for (long long a = 1; a <= bound; a *= x) { for (long long b = 1; a + b <= bound; b *= y) { seen.insert(static_cast<int>(a + b)); if (y == 1) break; } if (x == 1) break; } return {seen.begin(), seen.end()}; }};func powerfulIntegers(x int, y int, bound int) []int { seen := map[int]bool{} for a := 1; a <= bound; a *= x { for b := 1; a+b <= bound; b *= y { seen[a+b] = true if y == 1 { break } } if x == 1 { break } } out := make([]int, 0, len(seen)) for k := range seen { out = append(out, k) } return out}from typing import List
class Solution: def powerfulIntegers(self, x: int, y: int, bound: int) -> List[int]: seen = set() a = 1 while a <= bound: b = 1 while a + b <= bound: seen.add(a + b) if y == 1: break b *= y if x == 1: break a *= x return list(seen)function powerfulIntegers(x, y, bound) { const seen = new Set(); for (let a = 1; a <= bound; a *= x) { for (let b = 1; a + b <= bound; b *= y) { seen.add(a + b); if (y === 1) break; } if (x === 1) break; } return [...seen];}class Solution { public List<Integer> powerfulIntegers(int x, int y, int bound) { Set<Integer> seen = new HashSet<>(); for (long a = 1; a <= bound; a *= x) { for (long b = 1; a + b <= bound; b *= y) { seen.add((int) (a + b)); if (y == 1) break; } if (x == 1) break; } return new ArrayList<>(seen); }}function powerfulIntegers(x: number, y: number, bound: number): number[] { const seen: Set<number> = new Set(); for (let a = 1; a <= bound; a *= x) { for (let b = 1; a + b <= bound; b *= y) { seen.add(a + b); if (y === 1) break; } if (x === 1) break; } return [...seen];}Editorial#
log_2(10^6) ~ 20, so the double loop runs at most ~400 iterations. The x == 1 / y == 1 short-circuits prevent infinite loops where the base never grows. Using long long avoids overflow when computing a * x against the bound near INT_MAX.
Complexity#
- Time: O((log bound)^2).
- Space: O(M) where M is the number of distinct sums.
Concept revision#
Related#