Numbers within a range that can be expressed as power of two numbers
Last Updated :
23 Mar, 2023
Given two integers L and R. Find the number of perfect powers in the given range [L, R]. A number x is said to be perfect power if there exists some integers a > 0, p > 1 such that x = ap. Examples :
Input : 1 4
Output : 2
Explanation :
Suitable numbers are 1 and 4 where 1
can be expressed as 1 = 12
and 4 can be expressed as 4 = 22
Input : 12 29
Output : 3
Explanation :
Suitable numbers are 16, 25 and 27.
Prerequisites : Check if a number can be expressed as x^y, Binary Search and Perfect power (1, 4, 8, 9, 16, 25, 27, …) Approach : Let's fix some power p. It's obvious that there are no more than 1018/p numbers x such that xp doesn't exceed 1018 for a particular p. At the same time, only for p = 2 this amount is relatively huge, for all other p ? 3 the total amount of such numbers will be of the order of 106. There are 109 squares in the range [1, 1018], so can't store them to answer our query. Either, generate all of powers for p ? 2 and dispose of all perfect squares among them or generate only odd powers of numbers like 3, 5, 7, etc. Then answer to query (L, R) is equal to the amount of generated numbers between L and R plus some perfect squares in range.
- The number of perfect squares in the range is the difference of floor value of square root of R and floor value of square root of (L - 1), i.e. (floor(sqrt(R)) - floor(sqrt(L - 1)). Note that due to precision issues the standard sqrt might produce incorrect values, so either use binary search or sqrtl inbuilt function defined in cmath (Check here for more description of sqrtl).
- To generate those odd powers of numbers. First of all, do precomputation of finding such numbers that can be expressed as power of some number upto 1018 so that we can answer many queries and no need to process them again and again for each query. Start by iterating a loop from 2 to 106 (since we are calculating for powers p ? 3 and 106 is the maximum number whose power raised to 3 cannot exceed 1018), for each value we insert its square into a set and check further if that value is already a perfect square (already present in the set), we do not find any other powers of that number (since any power of a perfect square is also a perfect square). Otherwise, run an inside loop to find odd powers of the number until it exceeds 1018 and insert into another set say 's'. By this approach, we haven't pushed any perfect square in the set 's'.
Hence the final answer would be sum of number of perfect squares in the range and difference of upper value of R and lower value of L (using binary search). Below is the implementation of above approach in C++.
C++
// CPP Program to count the numbers
// within a range such that number
// can be expressed as power of some
// other number
#include <bits/stdc++.h>
using namespace std;
#define N 1000005
#define MAX 1e18
// Vector to store powers greater than 3
vector<long int> powers;
// set to store perfect squares
set<long int> squares;
// set to store powers other
// than perfect squares
set<long int> s;
void powersPrecomputation()
{
for (long int i = 2; i < N; i++)
{
// pushing squares
squares.insert(i * i);
// if the values is already
// a perfect square means
// present in the set
if (squares.find(i) != squares.end())
continue;
long int temp = i;
// run loop until some
// power of current number
// doesn't exceed MAX
while (i * i <= MAX / temp)
{
temp *= (i * i);
/* pushing only odd powers
as even power of a number
can always be expressed as
a perfect square which is
already present in set squares */
s.insert(temp);
}
}
// Inserting those sorted
// values of set into a vector
for (auto x : s)
powers.push_back(x);
}
long int calculateAnswer(long int L, long int R)
{
// calculate perfect squares in
// range using sqrtl function
long int perfectSquares = floor(sqrtl(R)) -
floor(sqrtl(L - 1));
// calculate upper value of R
// in vector using binary search
long int high = (upper_bound(powers.begin(),
powers.end(), R) - powers.begin());
// calculate lower value of L
// in vector using binary search
long int low = (lower_bound(powers.begin(),
powers.end(), L) - powers.begin());
// add into final answer
perfectSquares += (high - low);
return perfectSquares;
}
// Driver Code
int main()
{
// precompute the powers
powersPrecomputation();
// left value of range
long int L = 12;
// right value of range
long int R = 29;
cout << "Number of powers between " << L
<< " and " << R << " = " <<
calculateAnswer(L, R) << endl;
L = 1;
R = 100000000000;
cout << "Number of powers between " << L
<< " and " << R << " = " <<
calculateAnswer(L, R) << endl;
return 0;
}
Java
// JAVA Program to count the numbers
// within a range such that number
// can be expressed as power of some
// other number
import java.util.*;
public class Main {
static final int N = 1000005;
static final double MAX = 1e18;
// Vector to store powers greater than 3
static ArrayList<Long> powers = new ArrayList<>();
// set to store perfect squares
static TreeSet<Long> squares = new TreeSet<>();
// set to store powers other than perfect squares
static TreeSet<Long> s = new TreeSet<>();
public static void powersPrecomputation()
{
for (long i = 2; i < N; i++) {
// pushing squares
squares.add(i * i);
// if the value is already a perfect square
// means present in the set
if (squares.contains(i))
continue;
long temp = i;
// run loop until some power of current number
// doesn't exceed MAX
while (i * i <= MAX / temp) {
temp *= (i * i);
/* pushing only odd powers
as even power of a number can always be
expressed as a perfect square which is
already present in set squares */
s.add(temp);
}
}
// Inserting those sorted values of set into a
// vector
powers.addAll(s);
}
public static long calculateAnswer(long L, long R)
{
// calculate perfect squares in range using sqrt
// function
long perfectSquares
= (long)(Math.floor(Math.sqrt(R))
- Math.floor(Math.sqrt(L - 1)));
// calculate upper value of R in vector using binary
// search
int high = upperBound(powers, R);
// calculate lower value of L in vector using binary
// search
int low = lowerBound(powers, L);
// add into final answer
perfectSquares += (high - low);
return perfectSquares;
}
// Java equivalent of C++ upper_bound function
public static int upperBound(ArrayList<Long> arr,
long value)
{
int l = 0, r = arr.size();
while (l < r) {
int mid = l + (r - l) / 2;
if (arr.get(mid) <= value) {
l = mid + 1;
}
else {
r = mid;
}
}
return l;
}
// Java equivalent of C++ lower_bound function
public static int lowerBound(ArrayList<Long> arr,
long value)
{
int l = 0, r = arr.size();
while (l < r) {
int mid = l + (r - l) / 2;
if (arr.get(mid) < value) {
l = mid + 1;
}
else {
r = mid;
}
}
return l;
}
// Driver Code
public static void main(String[] args)
{
// precompute the powers
powersPrecomputation();
// left value of range
long L = 12;
// right value of range
long R = 29;
System.out.println("Number of powers between " + L
+ " and " + R + " = "
+ calculateAnswer(L, R));
L = 1;
R = 100000000000L;
System.out.println("Number of powers between " + L
+ " and " + R + " = "
+ calculateAnswer(L, R));
}
}
Python3
# Python Program to count the numbers
# within a range such that number
# can be expressed as power of some
# other number
import math
import bisect
N = 1000005
MAX = int(1e18)
# Vector to store powers greater than 3
powers = []
# set to store perfect squares
squares = set()
# set to store powers other
# than perfect squares
s = set()
def powersPrecomputation():
for i in range(2, N):
# pushing squares
squares.add(i * i)
# if the value is already
# a perfect square means
# present in the set
if i in squares:
continue
temp = i
# run loop until some
# power of current number
# doesn't exceed MAX
while i * i <= MAX / temp:
temp *= i * i
# pushing only odd powers
# as even power of a number
# can always be expressed as
# a perfect square which is
# already present in set squares
s.add(temp)
# Inserting those sorted
# values of set into a list
for x in sorted(s):
powers.append(x)
def calculateAnswer(L, R):
# calculate perfect squares in
# range using sqrt function
perfectSquares = math.floor(math.sqrt(R)) - math.floor(math.sqrt(L - 1))
# calculate upper value of R
# in list using binary search
high = len(powers) if R >= powers[-1] else bisect.bisect_right(powers, R)
# calculate lower value of L
# in list using binary search
low = bisect.bisect_left(powers, L)
# add into final answer
perfectSquares += (high - low)
return perfectSquares
# Driver Code
if __name__ == "__main__":
# precompute the powers
powersPrecomputation()
# left value of range
L = 12
# right value of range
R = 29
print("Number of powers between", L,
"and", R, "=", calculateAnswer(L, R))
L = 1
R = 100000000000
print("Number of powers between", L,
"and", R, "=", calculateAnswer(L, R))
# this code is contributed by rutikbhosale
C#
// C# Program to count the numbers
// within a range such that number
// can be expressed as power of some
// other number
using System;
using System.Collections.Generic;
using System.Linq;
class Program {
const int N = 1000005;
const double MAX = 1e18;
static List<long> powers = new List<long>();
static HashSet<long> squares = new HashSet<long>();
static HashSet<long> s = new HashSet<long>();
static void PowersPrecomputation()
{
// add 1 to squares
squares.Add(1);
for (long i = 2; i < N; i++) {
// pushing squares
squares.Add(i * i);
// if the values is already
// a perfect square means
// present in the set
if (squares.Contains(i))
continue;
long temp = i;
// run loop until some
// power of current number
// doesn't exceed MAX
while (i * i <= MAX / temp) {
temp *= (i * i);
/* pushing only odd powers
as even power of a number
can always be expressed as
a perfect square which is
already present in set squares */
s.Add(temp);
}
}
// Inserting those sorted
// values of set into a list
powers = s.ToList();
powers.Sort();
// add 1 to powers
powers.Insert(0, 1);
}
static long CalculateAnswer(long L, long R)
{
// calculate perfect squares in
// range using Math.Sqrt function
long perfectSquares
= (long)Math.Floor(Math.Sqrt(R))
- (long)Math.Floor(Math.Sqrt(L - 1));
// calculate upper value of R
// in list using binary search
long high = powers.BinarySearch(R);
if (high < 0)
high = ~high;
// calculate lower value of L
// in list using binary search
long low = powers.BinarySearch(L);
if (low < 0)
low = ~low;
// add into final answer
perfectSquares += (high - low);
return perfectSquares;
}
static void Main(string[] args)
{
// precompute the powers
PowersPrecomputation();
// left value of range
long L = 12;
// right value of range
long R = 29;
Console.WriteLine("Number of powers between " + L
+ " and " + R + " = "
+ CalculateAnswer(L, R));
L = 1;
R = 100000000000;
Console.WriteLine("Number of powers between " + L
+ " and " + R + " = "
+ CalculateAnswer(L, R));
}
}
// this code is contributed by rutikbhosale
JavaScript
// JavaScript function to count the numbers
// within a range such that number
// can be expressed as power of some
// other number
const N = 1000005;
const MAX = 1e18;
// Array to store powers greater than 3
let powers = [];
// Set to store perfect squares
let squares = new Set();
// Set to store powers other
// than perfect squares
let s = new Set();
function powersPrecomputation() {
for (let i = 2; i < N; i++) {
// adding squares to set
squares.add(i * i);
// if the values is already
// a perfect square means
// present in the set
if (squares.has(i)) continue;
let temp = i;
// run loop until some
// power of current number
// doesn't exceed MAX
while (i * i <= MAX / temp) {
temp *= i * i;
/* adding only odd powers
as even power of a number
can always be expressed as
a perfect square which is
already present in set squares */
s.add(temp);
}
}
// Adding those values of set into an array
for (let x of s) powers.push(x);
}
function calculateAnswer(L, R) {
// calculate perfect squares in
// range using Math.floor(Math.sqrt(R))
let perfectSquares =
Math.floor(Math.sqrt(R)) - Math.floor(Math.sqrt(L - 1));
// calculate upper value of R
// in array using binary search
let high = powers.filter((p) => p <= R).length;
// calculate lower value of L
// in array using binary search
let low = powers.filter((p) => p >= L).length;
// add into final answer
perfectSquares += high - low;
return perfectSquares;
}
// Driver code
let L = 12;
let R = 29;
console.log(
"Number of powers between " +
L +
" and " +
R +
" = " +
calculateAnswer(L, R)
);
L = 1;
R = 100000000000;
console.log(
"Number of powers between " +
L +
" and " +
R +
" = " +
calculateAnswer(L, R)
);
// this code is contributed by devendra1
OutputNumber of powers between 12 and 29 = 3
Number of powers between 1 and 100000000000 = 320990
Similar Reads
Check if a number can be expressed as x^y (x raised to power y)
Given a positive integer n, find if it can be expressed as xy where y > 1 and x > 0. x and y both are integers. Examples : Input: n = 8 Output: true 8 can be expressed as 23 Input: n = 49 Output: true 49 can be expressed as 72 Input: n = 48 Output: false 48 can't be expressed as xyRecommended
11 min read
Check if a number can be expressed as sum of two Perfect powers
Given a positive integer n, the task is to check whether n can be expressed in the form of ax + by where x and y > 1 and a and b >= 0. If n can be expressed in the given form then print "Yes", otherwise print "No".Examples:Input: n = 5Output: YesExplanation: 5 can be expressed as 22 + 12 Input
5 min read
Check if a number can be expressed as power | Set 2 (Using Log)
Check if a number can be expressed as x^y (x raised to power y) Given a positive integer n, find if it can be expressed as x^y where y > 1 and x > 0. x and y both are integers.Examples : Input: n = 8 Output: true 8 can be expressed as 2^3 Input: n = 49 Output: true 49 can be expressed as 7^2 I
4 min read
Find ways an Integer can be expressed as sum of n-th power of unique natural numbers
Given two numbers x and n, find a number of ways x can be expressed as sum of n-th power of unique natural numbers. Examples : Input : x = 10, n = 2Output : 1Explanation: 10 = 12 + 32, Hence total 1 possibility Input : x = 100, n = 2Output : 3Explanation: 100 = 102 OR 62 + 82 OR 12 + 32 + 42 + 52 +
14 min read
Count numbers from a given range that can be expressed as sum of digits raised to the power of count of digits
Given an array arr[] consisting of queries of the form {L, R}, the task for each query is to count the numbers in the range [L, R] that can be expressed as the sum of its digits raised to the power of count of digits. Examples: Input: arr[][] = {{8, 11}}Output: 2Explanation:From the given range [1,
10 min read
Print all integers that are sum of powers of two given numbers
Given three non-negative integers x, y and bound, the task is to print all the powerful integer ? bound in sorted order. A powerful integer is of the form xi + yj for all i, j ? 0. Examples: Input: x = 3, y = 5, bound = 10 Output: 2 4 6 8 10 30 + 50 = 1 + 1 = 2 30 + 51 = 1 + 5 = 6 31 + 50 = 3 + 1 =
8 min read
Count of numbers in range [L, R] which can be represented as sum of two perfect powers
Given a range [L, R], the task is to find the count of numbers in the range [L, R] that can be expressed as a sum of two perfect powers.Examples:Input: L = 0, R = 1Output: 2Explanation:The valid numbers are:1 as it can be expressed as, 1 = 12 + 02.0 as it can be expressed as, 0 = 02 + 02.Therefore,
8 min read
Highest power of a number that divides other number | Set - 2
Given two numbers N and M(M > 1), the task is to find the highest power of M that divides N. Examples: Input: N = 12, M = 2Output: 2Explanation: The powers of 2 which divide 12 are 1 and 2 (21 = 2 and 22 = 4 which both divide 12). The higher power is 2, hence consider 2. Input: N = 500, M = 5Outp
5 min read
Elements of Array which can be expressed as power of some integer to given exponent K
Given an array arr[] of size N, and an integer K, the task is to print all the elements of the Array which can be expressed as a power of some integer (X) to the exponent K, i.e. XK.Examples: Input: arr[] = {46656, 64, 256, 729, 16, 1000}, K = 6 Output: 46656 64 729 Explanation: Only numbers 46656,
13 min read
Check if a number is a power of another number
Given two positive numbers x and y, check if y is a power of x or not.Examples : Input: x = 10, y = 1Output: Truex^0 = 1Input: x = 10, y = 1000Output: Truex^3 = 1Input: x = 10, y = 1001Output: False[Naive Approach] Repeated Multiplication MethodThis approach checks whether a number y is a power of a
8 min read