Algorithm description

Finding $a^n$ involves doing $n$ multiplications of $a$, the same operation can be done in $O(log(n))$ multiplications

For any number $a$ raised to an even power:

$$ a^n = (a^{n/2})^2 = a^{n/2} \cdot a^{n/2} $$

For any number $a$ rasied to an odd power:

$$ a^n = a^{n - 1} \cdot a $$

Implementation

Time complexity: $O(log(n))$

/**
 * Computes
 *
 *    a^k
 *
 * Given the following facts:
 *
 * - if `k` is even then a^(2k) = (a^k)^2
 * - if `k` is odd then a^(2k + 1) = (a^k)^2 * a
 */
int logarithmic_exponentiation(int a, int k) {
  if (k == 0) {
    // a^0 = 1
    return 1;
  }
  if (k % 2 == 1) {
    return binary_exponentiation(a, k - 1) * a;
  } else {
    int t = binary_exponentiation(a, k / 2);
    return t * t;
  }
}

// iterative implementation
int binary_exponentiation(int a, int k) {
  int x = 1;
  while (k) {
    // analyze the i-th bit of the binary representation of k
    if (k & 1) {
      x *= a;
    }
    a *= a;
    k >>= 1;
  }
  return x;
}