372-super-pow
Question
https://leetcode.com/problems/super-pow/description/
Your task is to calculate ab mod 1337 where a is a positive integer and b is an extremely large positive integer given in the form of an array.
Example:
a = 2
b = [3]
Result: 8
a = 2
b = [1,0]
Result: 1024
Thought Process
- Modular Exponentiation
- It's useful in the field of public-key cryptography, https://en.wikipedia.org/wiki/Modular_exponentiation
- c mod m = (a ⋅ b) mod m = [(a mod m) ⋅ (b mod m)] mod m
- Starting from the front, we do the powMod the base with the corresponding digit
- Then, we need to remember to powMod the previous result with 10
- Time complexity O(n)
- Space complexity O(1)
- Euler's Theorem/Fermat's Little Theorem
- Euler's theorem, [[https://en.wikipedia.org/wiki/Euler's_theorem](https://en.wikipedia.org/wiki/Euler's_theorem](https://en.wikipedia.org/wiki/Euler's_theorem](https://en.wikipedia.org/wiki/Euler's_theorem)\)
- Fermat's little theorem, [[https://en.wikipedia.org/wiki/Fermat's_little_theorem](https://en.wikipedia.org/wiki/Fermat's_little_theorem](https://en.wikipedia.org/wiki/Fermat's_little_theorem](https://en.wikipedia.org/wiki/Fermat's_little_theorem)\)
- Euler's totient function, [[https://en.wikipedia.org/wiki/Euler's_totient_function](https://en.wikipedia.org/wiki/Euler's_totient_function](https://en.wikipedia.org/wiki/Euler's_totient_function](https://en.wikipedia.org/wiki/Euler's_totient_function)\)
- Examples, http://mathonline.wikidot.com/examples-using-euler-s-theorem
- Three cases for reducing the power
- a is multiple of 1337, result is 0
- a is coprime of 1337, then a ^ b % 1337 = a ^ (b % phi(1337)) % 1337
- a has divisor of 7 or 191,
- phi(1337) = phi(7 * 191) = 6 * 190 = 1140
- a ^ b mod 1337 = a ^ x mod 7, where x = b mod 1140
Solution
class Solution {
public int superPow(int a, int[] b) {
int k = 1337;
a %= k;
int result = 1;
for (int i = 0; i < b.length; i++) {
result = powMod(result, 10, k) * powMod(a, b[i], k) % k;
}
return result;
}
private int powMod(int a, int b, int k) {
int result = 1;
while (b != 0) {
if (b % 2 != 0) result = result * a % k;
a = a * a % k;
b /= 2;
}
return result;
}
}
class Solution {
public int superPow(int a, int[] b) {
if (a % 1337 == 0) return 0;
int k = 1337, phi = 1140;
a %= k;
int p = 0;
for (int i : b) p = (p * 10 + i) % phi;
if (p == 0) p += 1140;
return powMod(a, p, k);
}
private int powMod(int a, int b, int k) {
int result = 1;
while (b != 0) {
if (b % 2 != 0) result = result * a % k;
a = a * a % k;
b /= 2;
}
return result;
}
}