快速幂

简介:快速幂算法可以将a^k%p以O(log k)的时间复杂度算出来。其中a和p在1e9左右的范围内都可以。

原理:我们先求出来a^(2^0)、a^(2^1)、a^(2^2)、a^(2^3)。。。a^(2^log k),然后将a^k用前面那些式子的乘积的形式表示出来,至于模p,在那些式子后面分别模p就行了。

快速幂的原理用的是平方法。观察a^(2^0)、a^(2^1)、a^(2^2)、a^(2^3)。。。a^(2^log k)这些式子,其实后一个数都是前一个数的平方。

怎样将a^k用^(2^0)、a^(2^1)、a^(2^2)、a^(2^3)。。。a^(2^log k)的乘积表示出来呢?很简单。假设a^k=a^(2^x1) * a^(2^x2) * ...*a^(2^xt),那么a^k就等于a^(2^x1+2^x2+...2^xt),也就是我们要让k等于2^x1+2^x2+...2^xt,怎样让它们俩相等呢?很简单。这其实就是求一下k的二进制编码而已。比如k的二进制表示为10011,那么k就等于1*2^0+1*2^1+0*2^2+0*2^3+0*2^4+1*2^5.

ok,那么快速幂的原理就是先将k用二进制表示,然后通过二进制将k用a^(2^0)、a^(2^1)、a^(2^2)、a^(2^3)。。。a^(2^log k)的乘积表示,中间注意取模就行了。

时间复杂度:快速幂程序中的循环其实是k的二进制位数,即log k(以2为底),因此你写一个快速幂的函数,时间复杂度为O(log k)。

//快速幂,求a^k%p 
ll qsm(ll a,ll k,ll p)
{
	ll res=1;//先把res处理为1,便于以后相乘
	while(k)
	{
		if(k&1) res=res*a%p;//如果k的最后一位为1,那么结果累乘a 
		k>>=1;//k右移一位,为了遍历k的每一位 
		a=a*a%p;//a是累乘的,从a^1累乘到a^(log k) 
	}
	
	return res; 
}

随便写出来划划水。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值