我们需要求ab模上一个数的值,例如P372超级次方
我们首先直到模运算的的乘法律(a * b) % p = (a % p * b % p) % p,因此只要每一步乘法运算都取模运算,最后的结果也是取模的结果。
我们考虑ab,当b是奇数时,可以分解为a * a(b-1),而(b-1)是偶数,我们可以直接带到b是偶数的情形,当b是偶数时,ab=(a*a)b/2,这样我们就可以继续分解,记录结果,并在每一步乘法中对p取模,从而达到计算ab对p取模的结果。
递归解法:
int fastpawer(int a,int b){
a=a%Mod; //注意一定要先对a取模,不然a*a可能溢出
if(b==1) return a;
if(b==0) return 1;
if(b%2==1) return a*fastpawer(a*a,b/2)%Mod;
else return fastpawer(a*a,b/2)%Mod;
}
迭代解法:
int fastpawer(int a,int b){
a=a%Mod;
int res=1;
while(b){
if(b&1) res=res*a%Mod;
b>>=1;
a=a*a%Mod;
}
return res;
}
事实上,当a相同时,我们用递归解法求解时,做了很多重复工作,因此我们可以采用记忆化的方法:用一个数组储存递归的结果,从而达到用空间换时间的效果。