LeetCode Super Pow(快速求幂算法)

来源:互联网 发布:苹果垃圾桶 知乎 编辑:程序博客网 时间:2024/04/30 06:38

题意:给出底数a,指数b(很大的数,用数组形式给出,每个元素为1位),求其对1337的模

思路:在遍历数据过程中,用ans(n)表示上一次计算结果,则ans(n+1) = pow(ans(n), 10, 1337) * pow(a, b[n+1], 1337) % 1337

其中pow(a, b, mod)为快速求幂算法的实现

具体代码如下:耗时(9ms)

public class Solution{    private int pow(int a, int b, int mod)    {        int ret = 1;        int x = a % mod;        while (b != 0) {            if ((b & 1) == 1) {                ret = ret * x % mod;            }            x = x * x % mod;            b >>= 1;        }        return ret;    }    public int superPow(int a, int[] b)    {        int ans = 1;        int mod = 1337;        for (int i = 0; i < b.length; i++) {            ans = pow(ans, 10, mod) * pow(a, b[i], mod) % mod;        }        return ans;    }}

第二种解法 (使用欧拉函数和快速求幂)

(1) Firstly, if a has both divisor 7 and 191, that's a % 1337 == 0, answer is 0.
(2) Then if a has neither divisor 7 nor 191, that's a and 1337 are coprime, so ab % 1337 = ab % phi(1337) % 1337 = ab % 1140 % 1337.

(3) Finally, a could has either divisor 7 or 191, that's similar.
Let it be 7 for example.
Let a = 7nx
and let b = 1140p + q, where 0 < q <= 1140
then:

ab % 1337
= ((7nx)b) % 1337
= (7nbxb) % 1337
= ( (7nb % 1337) * (xb % 1337) ) % 1337
= ( (71140np + nq % 1337) * (x1140p + q % 1337) ) % 1337

now note x and 1337 are coprime, so

= ( (71140np + nq % 1337) * (xq % 1337) ) % 1337
= ( 7 * (71140np + nq - 1 % 191) * (xq % 1337) ) % 1337

note 7 and 191 are coprime too, and 1140 is a multiple of 190, where 190 = phi(191). What's more we should assure that q != 0, if b % 1140== 0, then let b = 1140. so

= ( 7 * (7nq - 1 % 191) * (xq % 1337) ) % 1337
= ( (7nq % 1337) * (xq % 1337) ) % 1337
= (7nqxq) % 1337
= ((7nx)q) % 1337
= (aq) % 1337

public class Solution{    private int pow(int a, int b, int mod)    {        int ret = 1;        int x = a % mod;        while (b != 0) {            if ((b & 1) == 1) {                ret = ret * x % mod;            }            x = x * x % mod;            b >>= 1;        }        return ret;    }    public int superPow(int a, int[] b)    {        int mod = 1337;        int q = 0;        for (int num : b) {            q = (q * 10 + num) % mod;        }        if (q == 0) q = 1140;        return pow(a, q, mod);    }}


0 0
原创粉丝点击