1、给定三个正整数:a,b,c(a<, b<
, 1<m<
),求
%m。
时间复杂度为O(b)的代码:
typedef long long LL;
LL pow(LL a,LL b,LL m)
{
LL ans = 1;
for(int i=0;i<b;i++)
{
ans=ans*a%m;
}
return ans;
}
代码中使用long long 而不用int 的原因是防止两个int 变量相乘后溢出。
1、给定三个正整数:a,b,c(a<, b<
, 1<m<
),求
%m。
O(b)的复杂度连支持b<都已经很难了,更何况
。
这里要使用快速幂的思想,它基于二分的思想,因此也称为二分幂。
- 如果b是奇数,那么有
=
*
- 如果b是偶数,那么有
=
*
显然,b是奇数的情况下总可以在下一步转换为b是偶数的情况,而b是偶数的情况总可以在下一步转换为b/2的情况。这样,在log(b)级别次数转换后,就可以把b变为0,而任何正整数的0次方都是1。
快速幂的递归写法,时间复杂度为O(log b)
typedef long long LL
LL binaryPow(LL a,LL b,LL m)
{
if(b == 0) return 1;//如果b为0,那么a^0=1
if(b % 2 ==1)//b为奇数,转为b-1
return a * binaryPow(a, b-1, m) % m;
else//b为偶数,转为b/2
{
LL mul = binaryPow(a, b / 2, m);
return mul * mul % m;
}
}
上面的代码中,条件if(b%2==1)可以用if(b&1)代替,因为b&1进行位于操作,判断b的末位是否为1,这样写执行速度会快一点。
还要注意,当b%2==0时不要直接返回binaryPow(a, b/2, m)* binaryPow(a, b/2, m),这是因为调用了两次binaryPow()函数,导致时间复杂度变成O()=O(b);