Count the integers of the form 2^x * 3^y#9021

Count the integers of the form 2^x * 3^y (Editorial)

There are not so many numbers of the form 2^x * 3^y that do not exceed 10^{18}. We can generate them and store them in an array .

The number of such values f(a, b) in the range can be found using the formula:

f(0, b) - f(0, a - 1)

Here, f(0, q) represents the number of values of the form 2^x * 3^y that do not exceed . This can be efficiently found using binary search on the array .

Example

Let’s generate all numbers of the form 2^x * 3^y that do not exceed .

The interval contains numbers (highlighted in blue).

The interval contains numbers (highlighted in green).

Let's find the solution for the interval :

upper\_bound(v.begin(), v.end(), 20) - upper\_bound(v.begin(), v.end(), 9) = 3

Indeed, the interval contains numbers of the desired form:

12, 16, 18

Algorithm implementation

Let's define the constant MAX = 10^{18} and an array .

#define MAX 1000000000000000000LL
vector<long long> v;

The function preprocess generates all numbers of the form 2^x * 3^y that do not exceed 10^{18} and stores them in the array . For each value of x = 1, 2, 4, 8, ... iterate over numbers y = 1, 3, 9, 27, ... until x * y < MAX.

void preprocess()
{
  long long x = 1, y = 1;
  while (x < MAX)
  {
    while (x * y < MAX)
    {
      v.push_back(x * y);
      y *= 3;
    }
    x *= 2;
    y = 1;
  }

Sort the numbers in the array .

  sort(v.begin(), v.end());
}

The main part of the program. Generate the array of numbers of the form 2^x * 3^y.

preprocess();

Read a query — the interval . The number of desired integers in this interval is computed using the formula:

f(a, b) = f(0, b) - f(0, a - 1)
while (scanf("%lld %lld", &a, &b) == 2)
{
  res = upper_bound(v.begin(), v.end(), b) – upper_bound(v.begin(), v.end(), a - 1);
  printf("%lld\n", res);
}