快速幂取模

快速幂取模就是在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


 

进阶版大数取模:

LeetCode 372.Super Pow

你的任务是计算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;
    }
};

 

posted on 2019-08-08 19:43  zkfopen  阅读(271)  评论(0编辑  收藏  举报

导航