Official

B - A^A Editorial by en_translator


First of all, let us roughly determine the approach; this time, we will try exhaustive search over \(A\). That is,

  • we exhaustively enumerate \(A\) within a specific range, and check if \(A^A = B\) holds for each \(A\).

Here, the problem is:

  • what is the appropriate “specific range”?
  • how can we determine if \(A^A = B\)?

We describe these points.

First, we describe the “specific range.” \(A^A\) increases as \(A\) does. Since \(B\) is between \(1\) and \(10^{18}\), we find the following fact:

  • Let \(x\) be the real number with \(x^x = 1\), and \(y\) be the one with \(y^y = 10^{18}\); then we only have to search within the range \(x \leq A \leq y\).

Thus, we can set an appropriate upper and lower bound for \(A\).
What are the actual bounds? First, \(1^1 = 1\), so the lower bound is \(1\).
Now we consider the upper bound of \(A\). We can easily derive it by an experiment:

\[15^{15} = 437893890380859375 \simeq 4.38 \times 10^{17},\]

\[16^{16} = 18446744073709551616 \simeq 1.84 \times 10^{19},\]

so the real value \(y\) such that \(y^y = 10^{18}\) is between \(15\) and \(16\), and we can set the upper bound of \(A\) to be \(15\).
Note that if you do not set the upper bound of \(A\), it may lead to an overflow in some languages, leading to a wrong decision.

Next, we describe how to determine if \(A^A = B\).
Some languages have pow function (such as std::pow in C++ and math.pow in Python), which seems straightforward, but using such a function may cause an error due to the floating point number type (that represents a decimal).
For example, if we calculate \(15^{15}\) in two ways, one with pow function and the other with an integer type, the result will be like as follows:

  • code
#include <cmath>
#include <iostream>
using namespace std;

int main() {
  {
    long long x = pow(15, 15);
    cout << x << endl;
  }
  {
    long long x = 1;
    for (int i = 0; i < 15; i++) x *= 15;
    cout << x << endl;
  }
}
  • result
437893890380859392
437893890380859375

Since \(15^{15} = 437893890380859375\), we notice that the former way causes an error.
To avoid such an issue, it is good idea to avoid decimals and stick to integer type when treating huge integers.

With the points so far, the problem can be solved. The following is sample code in C++.

#include <iostream>
using namespace std;

int main() {
  long long B;
  cin >> B;
  for (int A = 1; A <= 15; A++) {
    long long x = 1;
    for (int i = 0; i < A; i++) x *= A;
    if (x == B) {
      cout << A << endl;
      exit(0);
    }
  }
  cout << "-1" << endl;
}

posted:
last update: