1、处理b,b是个数组,无法组成一个整型,因此a的b次方需要特别处理。处理方法是采取递归的方法,
例如b = 1,5,6,4,因此a的b次方 = a^4 * (a的1,5,6次方)的10次方,因此就可以看到把原来的a的1564次方转化为子问题a的156次方,即superpow
2、常数次方的处理,由于这里的常数是1到9,a的数值有可能会很大导致a的常数次方超出整型,因此题目要求(a * b) % base,a * b可能会溢出。
证明可得(a * b) % base = (a % base)(b % base) % base,即等价于每个因子求模后再对乘积求模
即mypow
实现部分
1、注释的部分采用的是for循环求常数幂,这里先对a求模,对应的是乘数因子求模,res求模的意义是每次乘积都需要求模
时间复杂度是O(b.size())
2、未注释部分采用的是快速幂,时间复杂度为O(log(b.size()))。这里可能会有个疑惑就是为什么每次递归后、乘积后都需要取模?虽然是符合了上面的规律但这样做好像算式中取模次数好像非常多?个人理解是只要符合因子取模、乘积取模即可,不管取模多少次,结果都不会变,即9模2不管模多少次都是1,所以多次取模不影响结果,而且还可以防止溢出问题
class Solution {
public:
int base = 1337;
int mypow(int a,int k){
if(k == 0)return 1;
a %= base;
if(k % 2 == 1){
return (a * mypow(a,k - 1)) % base;
}
else{
int sub = mypow(a,k / 2);
return (sub * sub) % base;
}
}
/*
int mypow(int a,int k){
a %= base;
int res = 1;
for(int _ = 0;_ < k;++_){
res *= a;
res %= base;
}
return res;
}
*/
int superPow(int a, vector<int>& b) {
if(b.empty())return 1;
int last = b.back();
b.pop_back();
int part1 = mypow(a,last);
int part2 = mypow(superPow(a,b),10);
return (part1 * part2) % base;
}
};