345,超级次方

想了解更多数据结构以及算法题,可以关注微信公众号“数据结构和算法”,每天一题为你精彩解答。也可以扫描下面的二维码关注
在这里插入图片描述

你的任务是计算 a^b 对 1337 取模,a 是一个正整数,b 是一个非常大的正整数且会以数组形式给出。

示例 1:

输入: a = 2, b = [3]
输出: 8

示例 2:

输入: a = 2, b = [1,0]
输出: 1024


答案:

public int superPow1(int a, int[] b) {
    int res = 1;
    for (int i : b) {
        res = pow(res, 10) * pow(a, i) % 1337;
    }
    return res;
}

int pow(int x, int y) {
    if (y == 0)
        return 1;
    if (y == 1)
        return x % 1337;
    return pow(x % 1337, y / 2) * pow(x % 1337, y - y / 2) % 1337;
}

解析:

这题其实更像是一道数学题,要想解这题我们要明白这样一个公式

(a*b)%k=(a%k)*(b%k)%k,很好证明,这里就不在过多解释。上面pow函数使用递归的方式求解x^y,并且每次运算都会对1337求余,举个例子,如果求3^18,我们只需要求3^9然后再相乘即可,如果求3^9,我们只需要求3^4和3^5的乘积即可。代码第4行我们把它想象成一个数组转换为数字这样一个过程,就很容易理解了。下面我们再来看种解法

public int superPow(int a, int[] b) {
    int res = 1;
    int p = a;
    for (int i = b.length - 1; i >= 0; i--) {
        res = res * pow(p, b[i], 1337) % 1337;
        p = pow(p, 10, 1337);
    }
    return res;
}

public int pow(int a, int b, int c) {
    long res = 1;
    long p = a;
    while (b > 0) {
        if ((b & 1) == 1) {
            res = (res * p) % c;
        }
        p = (p * p) % c;
        b >>= 1;
    }
    return (int) (res % c);
}

函数pow代码很好理解,第15行先判断b是否是奇数,然后再计算。superPow函数中我们首先要明白a^(bc)=(a^b)^c这样一个公式才能看懂上面的代码,比如3^20=(3^10)^2。下面再来看最后一种解法

public int superPow2(int a, int[] b) {
    if (a % 1337 == 0)
        return 0;
    int p = 0;
    for (int i : b)
        p = (p * 10 + i) % 1140;
    if (p == 0)
        p += 1440;
    return power(a, p, 1337);
}

public int power(int a, int b, int c) {
    long res = 1;
    long p = a;
    while (b > 0) {
        if ((b & 1) == 1) {
            res = (res * p) % c;
        }
        p = (p * p) % c;
        b >>= 1;
    }
    return (int) (res % c);
}

这种解法如果看不懂的话,可以忽略。我估计有部分同学是看不懂的,因为这里涉及到一个定理,叫欧拉定理,也叫费马-欧拉定理。下面简单提示一下

1337的因数中除了1和他本身以外,还可以分解为1337=7*191,并且7和191都是质数,也称为素数,φ(7)=6,φ(191)=190,

所以φ(1337)=φ(7)*φ(191)=6*190=1140;

φ(a)表示的是比a小的正整数中与a互素的数的个数。


在这里插入图片描述

posted @ 2020-09-26 20:45  数据结构和算法  阅读(132)  评论(0编辑  收藏  举报