Super Pow
MedPrompt
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 1:
Input: a = 2, b = [3]
Output: 8Example 2:
Input: a = 2, b = [1,0]
Output: 1024Example 3:
Input: a = 1, b = [4,3,3,8,5,2]
Output: 1
Constraints:
1 <= a <= 231 - 11 <= b.length <= 20000 <= b[i] <= 9bdoes not contain leading zeros.
Approaches
2 approaches with complexity analysis and trade-offs.
This approach is based on the property of exponents x^(10y+z) = (x^y)^10 * x^z. We can process the digits of b from left to right. If we have already computed the result for a prefix of b, say res = a^(b_prefix) % 1337, and the next digit is d, the new number is b_prefix * 10 + d. The new result will be a^(b_prefix * 10 + d) % 1337, which simplifies to ( (a^(b_prefix))^10 * a^d ) % 1337. This can be calculated as ( power(res, 10, 1337) * power(a, d, 1337) ) % 1337. We can iterate through all digits of b and update the result accordingly.
Algorithm
- Initialize
result = 1. - Create a helper function
power(base, exp, mod)for modular exponentiation using the binary exponentiation method. - Iterate through each digit
din the input arraybfrom left to right. - In each iteration, update the
resultby applying the rulea^(10*x + d) = (a^x)^10 * a^d. The new result is calculated asresult = (power(result, 10, 1337) * power(a, d, 1337)) % 1337. - After iterating through all digits,
resultwill hold the final value ofa^b % 1337.
Walkthrough
This approach works by processing the digits of the large exponent b one by one from left to right. The core idea relies on the mathematical property x^(10y + z) = (x^y)^10 * x^z.
Let's say we have processed a prefix of b and calculated res = a^(prefix) % 1337. When we consider the next digit d, the new exponent becomes prefix * 10 + d. The new result can be calculated as a^(prefix * 10 + d) % 1337, which is equivalent to (a^(prefix * 10) * a^d) % 1337. This further simplifies to ((a^prefix)^10 * a^d) % 1337.
Since we already have res = a^(prefix) % 1337, the updated result is (power(res, 10, 1337) * power(a, d, 1337)) % 1337.
We start with a result of 1 (for an empty prefix) and iterate through all digits of b, updating the result in each step.
A helper function for modular exponentiation, power(base, exp), is used to efficiently compute powers under a modulus. This function uses the binary exponentiation (or exponentiation by squaring) algorithm.
class Solution { private int MOD = 1337; public int superPow(int a, int[] b) { if (a % MOD == 0) return 0; a %= MOD; int result = 1; for (int digit : b) { result = (power(result, 10) * power(a, digit)) % MOD; } return result; } // Computes (base^exp) % MOD using binary exponentiation private int power(int base, int exp) { int res = 1; base %= MOD; while (exp > 0) { if (exp % 2 == 1) { res = (int)((long)res * base % MOD); } base = (int)((long)base * base % MOD); exp /= 2; } return res; }}Complexity
Time
O(k), where `k` is the number of digits in `b`. The loop runs `k` times. Inside the loop, we call the `power` function with small, constant exponents (10 and a single digit d < 10). The complexity of `power(base, exp)` is `O(log exp)`, which is `O(1)` for constant exponents. Thus, the total time complexity is `O(k)`.
Space
O(1), as we only use a few variables to store intermediate results.
Trade-offs
Pros
Simple to understand and implement.
Does not require advanced number theory concepts.
Generalizes to any modulus, not just 1337.
Cons
May be slightly less performant than a number-theory-based approach due to repeated modular exponentiation with a large modulus inside the loop, leading to a larger constant factor in its time complexity.
This approach leverages number theory to optimize the calculation. The modulus is 1337 = 7 * 191. We can compute a^b mod 7 and a^b mod 191 separately and then combine the results using the Chinese Remainder Theorem (CRT). To compute a^b mod p (where p is prime), we use Fermat's Little Theorem, which states x^(p-1) ≡ 1 (mod p). This means we only need the exponent b modulo p-1. So, we first compute b % 6 and b % 190 and then use these smaller exponents to find the result modulo 7 and 191, which are then combined to get the final answer.
Algorithm
- Factor the modulus:
1337 = 7 * 191. - The problem
x = a^b % 1337is split into a system of congruences:x ≡ a^b (mod 7)andx ≡ a^b (mod 191). - To solve these, we use Fermat's Little Theorem, which reduces the exponent
bmodulop-1. We need to computeb % 6andb % 190. - The remainders
b % mare calculated by iterating through the digits ofb:rem = (rem * 10 + digit) % m. - Handle the edge case where
b % (p-1) == 0. The effective exponent should bep-1, not0. - Calculate
res1 = a^b (mod 7)andres2 = a^b (mod 191)using the reduced exponents. - Combine
res1andres2using the Chinese Remainder Theorem (CRT) to find the unique solutionxmodulo 1337.
Walkthrough
This advanced approach uses number theory to find the solution more efficiently. The modulus 1337 is not a prime number; it can be factored into 7 * 191. This allows us to use the Chinese Remainder Theorem (CRT).
The problem of finding x = a^b % 1337 is broken down into solving a system of two congruences:
x ≡ a^b (mod 7)x ≡ a^b (mod 191)
To solve each congruence, we use Fermat's Little Theorem. This implies that the exponent b can be reduced modulo p-1. So, we need to compute b % (7-1) = b % 6 and b % (191-1) = b % 190. The value of b modulo some number m can be found by iterating through its digits.
Once we have res1 = a^b % 7 and res2 = a^b % 191, we use the CRT to combine them. We look for a number x that satisfies both congruences. The solution will be unique modulo 7 * 191 = 1337.
The implementation requires pre-calculating the modular multiplicative inverse of 7 modulo 191, which is 82.
class Solution { private final int MOD = 1337; public int superPow(int a, int[] b) { if (a % MOD == 0) return 0; // Calculate b mod phi(7)=6 and b mod phi(191)=190 int b_mod_6 = getBModM(b, 6); if (b_mod_6 == 0) b_mod_6 = 6; // For b>=1, a^b = a^(phi) if b%phi=0 int b_mod_190 = getBModM(b, 190); if (b_mod_190 == 0) b_mod_190 = 190; // Calculate res1 = a^b mod 7 int res1 = power(a, b_mod_6, 7); // Calculate res2 = a^b mod 191 int res2 = power(a, b_mod_190, 191); // Use Chinese Remainder Theorem to find the unique solution // x ≡ res1 (mod 7) // x ≡ res2 (mod 191) // From x = 7k + res1, we get 7k + res1 ≡ res2 (mod 191) // k ≡ (res2 - res1) * modInverse(7, 191) (mod 191) // The modular inverse of 7 mod 191 is 82. int k = (res2 - res1 + 191) % 191; // Handle negative result k = (int)((long)k * 82 % 191); return res1 + 7 * k; } // Computes b % m private int getBModM(int[] b, int m) { int rem = 0; for (int digit : b) { rem = (rem * 10 + digit) % m; } return rem; } // Computes (base^exp) % mod private int power(int base, int exp, int mod) { int res = 1; base %= mod; while (exp > 0) { if (exp % 2 == 1) { res = (int)((long)res * base % mod); } base = (int)((long)base * base % mod); exp /= 2; } return res; }}Complexity
Time
O(k), where `k` is the length of `b`. Computing `b` modulo `6` and `190` each takes `O(k)` time. The modular exponentiation and CRT steps take constant time with respect to `k`. Therefore, the overall time complexity is dominated by processing the digits of `b`.
Space
O(1), as only a constant amount of extra space is used.
Trade-offs
Pros
More efficient in practice due to a smaller constant factor. The main loop to process
binvolves operations with small moduli (6 and 190), and the expensive modular exponentiation is done only a constant number of times.
Cons
Significantly more complex to understand and implement correctly.
Requires knowledge of number theory, including Fermat's Little Theorem and the Chinese Remainder Theorem.
The solution is tailored to the specific modulus
1337. If the modulus changes, it must be re-factored, and modular inverses must be recalculated.
Solutions
Solution
class Solution {private final int mod = 1337;public int superPow(int a, int[] b) { long ans = 1; for (int i = b.length - 1; i >= 0; --i) { ans = ans * qpow(a, b[i]) % mod; a = qpow(a, 10); } return (int)ans; }private long qpow(long a, int n) { long ans = 1; for (; n > 0; n >>= 1) { if ((n & 1) == 1) { ans = ans * a % mod; } a = a * a % mod; } return ans; }}class Solution {public: int superPow(int a, vector<int> &b) { using ll = long long; const int mod = 1337; ll ans = 1; auto qpow = [&](ll a, int n) { ll ans = 1; for (; n; n >>= 1) { if (n & 1) { ans = ans * a % mod; } a = a * a % mod; } return (int)ans; }; for (int i = b.size() - 1; ~i; --i) { ans = ans * qpow(a, b[i]) % mod; a = qpow(a, 10); } return ans; }};class Solution : def superPow ( self , a : int , b : List [ int ]) -> int : mod = 1337 ans = 1 for e in b [:: - 1 ]: ans = ans * pow ( a , e , mod ) % mod a = pow ( a , 10 , mod ) return ansVideo walkthrough
Newsletter
One sharp idea, every week
System design and interview prep — short enough to finish.
No spam. Unsubscribe anytime.
Practice
Same difficulty — related problems to reinforce the pattern.