2017-10-08 07:29:18 +00:00
|
|
|
"""
|
2023-10-10 05:52:37 +00:00
|
|
|
Binary Exponentiation
|
|
|
|
This is a method to find a^b in O(log b) time complexity
|
|
|
|
This is one of the most commonly used methods of exponentiation
|
|
|
|
It's also useful when the solution to (a^b) % c is required because a, b, c may be
|
|
|
|
over the computer's calculation limits
|
|
|
|
|
|
|
|
Let's say you need to calculate a ^ b
|
|
|
|
- RULE 1 : a ^ b = (a*a) ^ (b/2) ---- example : 4 ^ 4 = (4*4) ^ (4/2) = 16 ^ 2
|
|
|
|
- RULE 2 : IF b is odd, then a ^ b = a * (a ^ (b - 1)), where b - 1 is even
|
|
|
|
Once b is even, repeat the process until b = 1 or b = 0, because a^1 = a and a^0 = 1
|
|
|
|
|
|
|
|
For modular exponentiation, we use the fact that (a*b) % c = ((a%c) * (b%c)) % c
|
|
|
|
Now apply RULE 1 or 2 as required
|
|
|
|
|
|
|
|
@author chinmoy159
|
2017-10-08 07:29:18 +00:00
|
|
|
"""
|
|
|
|
|
|
|
|
|
2023-10-02 14:41:34 +00:00
|
|
|
def b_expo(a: int, b: int) -> int:
|
2023-10-10 05:52:37 +00:00
|
|
|
"""
|
|
|
|
>>> b_expo(2, 10)
|
|
|
|
1024
|
|
|
|
>>> b_expo(9, 0)
|
|
|
|
1
|
|
|
|
>>> b_expo(0, 12)
|
|
|
|
0
|
|
|
|
>>> b_expo(4, 12)
|
|
|
|
16777216
|
|
|
|
"""
|
2017-10-08 07:29:18 +00:00
|
|
|
res = 1
|
|
|
|
while b > 0:
|
2019-10-05 05:14:13 +00:00
|
|
|
if b & 1:
|
2017-10-08 07:29:18 +00:00
|
|
|
res *= a
|
|
|
|
|
|
|
|
a *= a
|
|
|
|
b >>= 1
|
|
|
|
|
|
|
|
return res
|
|
|
|
|
|
|
|
|
2023-10-02 14:41:34 +00:00
|
|
|
def b_expo_mod(a: int, b: int, c: int) -> int:
|
2023-10-10 05:52:37 +00:00
|
|
|
"""
|
|
|
|
>>> b_expo_mod(2, 10, 1000000007)
|
|
|
|
1024
|
|
|
|
>>> b_expo_mod(11, 13, 19)
|
|
|
|
11
|
|
|
|
>>> b_expo_mod(0, 19, 20)
|
|
|
|
0
|
|
|
|
>>> b_expo_mod(15, 5, 4)
|
|
|
|
3
|
|
|
|
"""
|
2017-10-08 07:29:18 +00:00
|
|
|
res = 1
|
|
|
|
while b > 0:
|
2019-10-05 05:14:13 +00:00
|
|
|
if b & 1:
|
|
|
|
res = ((res % c) * (a % c)) % c
|
2017-10-08 07:29:18 +00:00
|
|
|
|
|
|
|
a *= a
|
|
|
|
b >>= 1
|
|
|
|
|
|
|
|
return res
|