快速幂取模算法,即求(a^b) mod c =?.如果直接计算,代码如下:【时间复杂度为O(b)】
int ans=1;
for(int i=1;i<=b;i++)
{
ans=ans*a;
}
ans=ans%c;
【一】优化一:(a^b) mod c =[(a mod c)^b] mod c;
引理一:(ab) mod c=[(a mod c)*(b mod c)] mod c;
证明:令 a=a1*c+x1,b=b1*c+x2;
(a*b) mod c=[(a1*c+x1)*(b1*c+x2)] mod c;
=[a1b1c^2+a1x2c+x1b1c+x1x2] mod c;
=(x1x2) mod c;
=[(a mod c)*(b mod c)] mod c;
即:(ab) mod c=[(a mod c)*(b mod c)] mod c;
优化一代码:【时间复杂度为O(b),但是能防止a过大,溢出】
int ans=1;
a=a%c;
for(int i=1;i<=b;i++)
{
ans=ans*a;(1)
}
ans=ans%c;
利用引理一,再对步骤(1)进一步优化。
int ans=1;//【时间复杂度仍为O(b),但防止数据溢出】
a=a%c;
for(int i=1;i<=b;i++)
{
ans=(ans*a)%c;
}
ans=ans%c;
【二】优化二:a^b=(a^2)^(b/2);
如果b为奇数,则:
a^b=[(a^2)^(b/2)]*a;【注:计算机算两个整数相除时,商只能为整数。】
优化二代码【最终代码】:
int ans=1;//【时间复杂度为O(log(b))】
a=a%c;
while(b>0)
{
if(b%2= =1)
ans=(ans*a)%c;
b=b/2;
a=(a*a)%c;
}
参考百度文库。