关于快速幂取模计算的详细解释

首先对于幂和取模想必大家都不是很陌生,幂即一个数的多少次方,取模即取余运算:

下面咱们进行一个数的幂取模运算的最容易想到的方式:

a//底数

b//幂指数

c//取模数

//算法一:
int ans=1;
for(int t=1;t<=b;t++)
{ 
    ans=ans*a;
}
return ans%c;

时间复杂度为O(b),以上算法存在很大的一个问题在于多次求幂指数之后会超过整数类型的范围, 这是个很麻烦的问题

但是我们在离散数学或者数论中曾接触到这样一个定理或者公式

a^b mod c=(a mod c)^bmod c

由此可以想到刚才的另一种求的算法

//算法二:
int ans=1;
int a=a%c;
for(int t=1;t<=b;t++)
{
     ans=ans*a
}
return ans%c

既然a的求幂过程中可以先转化成a%c,那我们不难想到在循环ans时也可以%c从而控制数的大小

//算法三:
int ans=1;
int a=a%c;
for(int t=1;t<=b;t++)
{
  ans=(ans*a)%c;
}
return ans%c;

数字超出整型范围的问题几本解决了 ,那我们能不能去降低O(b)的时间复杂度呢

答案是肯定的:

我们可以根据b来进行一定量的缩减:

如果b是偶数,我们有如下公式

a^bmodc=(a^2modc)^b^/^2modc

同理奇数的公式也能相应的得到

a^bmodc=[((a^2)^b^/^2modc)*a]modc

这时,我们将a^2看做是一个变量k;

于是有了下面的代码

//算法4:
int ans=1;
int k;
a=a%c;
for(int t=1;t<=b/2;t++)
{
    k=(a*a)%c;
  
    
ans=(ans*k)%c;
}
if(b%2==1)
return (ans*a%c)%c;
else
return ans%c; 

此时我们的时间复杂度已经降到了O(b/2)

那我们还能不能再提高一下呢

答案依然是肯定的:

这是反复循环利用了算法四的思想

//算法5:
//已经成为一个函数
int quickpower(int x,int y,int z)
{
	int ans=1;
	x=x%z;
	while(y>0)
	{
		if(y%2==1)
		{
		  ans=(ans*x)%z;
		}
		y/=2;
		x=x*x%z;
	 }
	 return ans;
	 
}

时间复杂度为O(logb)一般情况基本不超时,

还请大佬多多交流——————QQ656484427

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

black-hole6

你的鼓励将是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值