快速幂取模
快速幂取模就是在O(logn)内求出an mod b的值。算法的原理是ab mod c=(a mod c)(b mod c)mod c
设计一个基于二分的递归算法
C++代码:
long exp_mod(long a,long n,long b)
{
long t;
if(n==0) return 1%b;
if(n==1) return a%b;
t=exp_mod(a,n/2,b);
t=t*t%b;
if((n&1)==1) t=t*a%b;
return t;
}
证明:ab mod c=(a mod c)(b mod c)mod c
假设
a = Ac + B;
b = Cc + D;
所以
a * b = ACc*c + ADc + BCc + BD;
a * b % c = BD % c;
a % c = B;
b % c = D;
(a % c)(b % c) % c = BD % c;
所以
ab % c = (a % c)(b % c) % c
进阶版大数取模:
你的任务是计算ab mod 1337,a是一个正整数和b是一个非常大的正整数数组的形式给出。
Example 1:
Input: a = 2, b = [3]
Output: 8
Example 2:
Input: a = 2, b = [1,0]
Output: 1024
思路:
参考:C++ Clean and Short Solution
一个知识点:ab mod c=(a mod c)(b mod c)mod c
因为这里的幂是一个数组,我们最好依次来处理数组的位数。
我们可以观察到:a1234567 % c = (a1234560 % c) * (a7 % c) % c = ((a123456)10) % c) * (a7 % c) % c
看起来有点复杂,我们换一种方式:
用f(a, b)来表示ab % c,然后使用 f 翻译上面的公式:
f(a,1234567) = f(a, 1234560) * f(a, 7) % c = f(f(a, 123456),10) * f(a,7)%c;
C++代码:
class Solution {
public:
const int base = 1337;
int superPow(int a, vector<int>& b) {
if(b.empty()) return 1;
int c = b.back();
b.pop_back();
return pow_mod(superPow(a, b), 10) * pow_mod(a, c) % base;
}
int pow_mod(int a, int k)
{
a = a % base;
int result = 1;
for(int i = 0; i < k; i++)
result = (result * a) % base;
return result;
}
};