Materi Fast Exponentiation

Download as pdf or txt
Download as pdf or txt
You are on page 1of 2

Last update: September 12, 2023 Translated From: e-maxx.

ru

Binary Exponentiation

Binary exponentiation (also known as exponentiation by squaring) is a trick which allows to calculate a
n
using only O(log n) multiplications
(instead of O(n) multiplications required by the naive approach).

It also has important applications in many tasks unrelated to arithmetic, since it can be used with any operations that have the property of
associativity:

(X ⋅ Y ) ⋅ Z = X ⋅ (Y ⋅ Z)

Most obviously this applies to modular multiplication, to multiplication of matrices and to other problems which we will discuss below.

Algorithm
Raising a to the power of n is expressed naively as multiplication by a done n − 1 times: a
n
= a ⋅ a ⋅ … ⋅ a . However, this approach is not
practical for large a or n .

a
b+c
= a
b
⋅ a
c
and 2b
a = a
b
⋅ a
b
= (a )
b 2
.

The idea of binary exponentiation is, that we split the work using the binary representation of the exponent.

Let's write n in base 2, for example:

13 11012 8 4 1
3 = 3 = 3 ⋅ 3 ⋅ 3

Since the number n has exactly ⌊log2 n⌋ + 1 digits in base 2, we only need to perform O(log n) multiplications, if we know the powers
⌊log n⌋
1 2 4
a ,a ,a ,a ,…,a
8 2
.

So we only need to know a fast way to compute those. Luckily this is very easy, since an element in the sequence is just the square of the
previous element.

1
3 = 3
2
2 1 2
3 = (3 ) = 3 = 9

2
4 2 2
3 = (3 ) = 9 = 81

2
8 4 2
3 = (3 ) = 81 = 6561

So to get the final answer for 3


13
, we only need to multiply three of them (skipping 3
2
because the corresponding bit in n is not set):
13
3 = 6561 ⋅ 81 ⋅ 3 = 1594323

The final complexity of this algorithm is O(log n) : we have to compute log n powers of a , and then have to do at most log n multiplications
to get the final answer from them.

The following recursive approach expresses the same idea:

⎧1 if n == 0
n 2
n (a 2
) if n > 0 and n even
a = ⎨
2
n−1
⎩ (a 2 ) ⋅ a if n > 0 and n odd
Implementation
First the recursive approach, which is a direct translation of the recursive formula:

long long binpow(long long a, long long b) {


if (b == 0)
return 1;
long long res = binpow(a, b / 2);
if (b % 2)
return res * res * a;
else
return res * res;
}

The second approach accomplishes the same task without recursion. It computes all the powers in a loop, and multiplies the ones with the
corresponding set bit in n . Although the complexity of both approaches is identical, this approach will be faster in practice since we don't
have the overhead of the recursive calls.

long long binpow(long long a, long long b) {


long long res = 1;
while (b > 0) {
if (b & 1)
res = res * a;
a = a * a;
b >>= 1;
}
return res;
}

Applications
Effective computation of large exponents modulo a number

Problem: Compute x
n
mod m . This is a very common operation. For instance it is used in computing the modular multiplicative inverse.

Solution: Since we know that the modulo operator doesn't interfere with multiplications ( a ⋅ b ≡ (a mod m) ⋅ (b mod m) (mod m) ), we
can directly use the same code, and just replace every multiplication with a modular multiplication:

long long binpow(long long a, long long b, long long m) {


a %= m;
long long res = 1;
while (b > 0) {
if (b & 1)
res = res * a % m;
a = a * a % m;
b >>= 1;
}
return res;
}

Note: It's possible to speed this algorithm for large b >> m . If m is a prime number x
n
≡ x
n mod (m−1)
(mod m) for prime m , and
x
n
≡ x
n mod ϕ(m)
(mod m) for composite m . This follows directly from Fermat's little theorem and Euler's theorem, see the article about
Modular Inverses for more details.

Effective computation of Fibonacci numbers

Problem: Compute n -th Fibonacci number Fn .

Solution: For more details, see the Fibonacci Number article. We will only go through an overview of the algorithm. To compute the next
Fibonacci number, only the two previous ones are needed, as Fn = Fn−1 + Fn−2 . We can build a 2 × 2 matrix that describes this
transformation: the transition from Fi and Fi+1 to Fi+1 and Fi+2 . For example, applying this transformation to the pair F0 and F1 would
change it into F1 and F2 . Therefore, we can raise this transformation matrix to the n -th power to find Fn in time complexity O(log n) .

You might also like