Super Pow
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: 8
Example 2:
Input: a = 2, b = [1,0]
Output: 1024
解答:
此题就是一道快递幂取模的变种,这里我不再解释快速幂取模算法。
- mod运算满足: ( a × b ) m o d m = ( a m o d m ) × ( b m o d m ) m o d m (a\times b) mod \ m = (a \ mod \ m) \times (b \ mod \ m) \ mod \ m (a×b)mod m=(a mod m)×(b mod m) mod m
- 题目中把b的每一位上的数字表示成数组中的元素,即
b
=
{
b
n
−
1
,
.
.
.
,
b
1
,
b
0
}
b = \{b_{n-1}, ..., b_1, b_0\}
b={bn−1,...,b1,b0}.
所以 a b = a b n − 1 . . . b i . . . b 0 = ∏ i = 0 n − 1 a 1 0 i b i = ∏ i = 0 n − 1 ( a 1 0 i ) b i a^b = a^{b_{n-1} ... b_i ... b_0}=\prod_{i=0}^{n-1}a^{10^ib_i} =\prod_{i=0}^{n-1}(a^{10^i})^{b_i} ab=abn−1...bi...b0=∏i=0n−1a10ibi=∏i=0n−1(a10i)bi, 我们可以记 a i = a 1 0 i = a i − 1 10 a_i = a^{10^i}=a_{i-1}^{10} ai=a10i=ai−110, 这样就可以高效的递推计算: a 1 0 i b i = a i − 1 10 × b i a^{10^ib_i}=a_{i-1}^{10\times b_i} a10ibi=ai−110×bi
综上, a b m o d m = ( ∏ i = 1 n ( a i m o d m ) b i m o d m ) m o d m a^b \ mod \ m = \left ( \prod_{i=1}^{n}(a_i \ mod \ m)^{b_i} mod \ m\right ) \ mod \ m ab mod m=(∏i=1n(ai mod m)bimod m) mod m
class Solution {
public:
int superPow(int a, vector<int>& b) {
if(b.empty()) return 0;
a %= 1337;
int a_i = a;
int res = fastmod(a, b[b.size()-1], 1337);
for(int i = b.size()-2; i >= 0; --i){
a_i = fastmod(a_i, 10, 1337); // 更新a_i
res = (res*fastmod(a_i, b[i], 1337) ) % 1337;
} return res;
}
private:
int fastmod(int base, int exp, int m){ // 快速幂取模
int res = 1;
base %= m;
while(exp != 0){
if(exp&1) {
res *= base;
res %= m;
}
base *= base;
base %= m;
exp >>= 1;
} return res;
}
};
2019.3.31 速度上居然打败了100%的人