超级次方

372. 超级次方

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

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

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

示例 3:
输入:a = 1, b = [4,3,3,8,5,2]
输出:1

示例 4:
输入:a = 2147483647, b = [2,0,0]
输出:1198

我们都知道

an+m == an + am

(an)m == anm


我们先忽略取模操作看一个例子

比如求 4235 那么输入应该是 4 {2 , 3 , 5}

变为求 ((42)10)10 * (43)10 * 45

先求 res = 42

循环 res = res10 * 43 --> 此时 res = (42)10 * 43

循环 res = res10 * 45 --> 此时 res = ((42)10 * 43)10 * 45 --> res = ((42)10)10 * ( 43)10 * 45

得到答案 , 退出

总结 : 循环--前面得到的值开 10 次方再乘以上后一位的值 , 作为下一次计算的值 , 循环到数组最后一位

加上取模操作方法不变


此时我们可以确保指数幂的位置为个位 ( n <= 9)

但是当底数很大时 , 如果直接使用 Math.pow(a , n) % 1337 或者 Math.pow(a % 1337 , n) % 1337 都会溢出

因为它是直接在 Math.pow(a , n) 或 Math.pow(a % 1337 , n) 就溢出了 , 我们无法在控制在每一步幂次时对数字取模限制其大小

所以要自己定义一个 myPow 递归方法


需要降幂 , 否则会出现溢出

那么我们可以从数组高位进行计算 , 即先求 ab[0]

上式可以变为 ab[0]/2 * ab[0]/2

但是要考虑 b[0] 奇偶性

  • 偶数时 , ab[0] == ab[0]/2 * ab[0]/2
  • 奇数时 , ab[0] == ab[0]/2 * ab[0]/2 * a

每一步遇到求次方或乘数后要对结果取模 %1337 (题中已给出)

改为以下

  • 偶数时 , ab[0] % 1337 ==( ab[0]/2 * ab[0]/2 ) % 1337
  • 奇数时 , ab[0] == (( ab[0]/2 * ab[0]/2 ) % 1337 * (a % 1337 )) % 1337

java 代码

int base = 1337;
//辅助方法
public int myPow(int a, int n) {
    if (n == 0) {
        return 1;
    }
    //递归, 确保每层返回后得到的 halfPow 都是对 1337 取模后的值
    int halfPow = myPow(a, n / 2) % base;
    int ret = (halfPow * halfPow) % base;
    if ((n & 1) == 1) {
        return (ret * (a % base)) % base;
    }
    return ret;
}
//主要方法
public int superPow(int a, int[] b) {
    int ans = 1;
    for (int i = 0; i < b.length; i++) {
        int p = myPow(a, b[i]);
        ans = ((myPow(ans, 10) % base) * (p % base)) % base;
    }
    return ans;
}

更新 (更好理解方法)

public int myPow(int a, int n) {
    int ret = 1;
    for (int i = 0; i < n; i++) {
        ret = ret * a % 1337;
    }
    return ret;
}
public int superPow(int a, int[] b) {
    a = a % 1337;
    int ans = 1;
    for (int i = 0; i < b.length; i++) {
        ans = (myPow(ans, 10) * myPow(a, b[i])) % 1337;
    }
    return ans;
}
posted @ 2021-12-05 13:08  猫杰瑞  阅读(93)  评论(0)    收藏  举报