快速幂

 

原理分析

       求a^n的值,按照传统的写法就是用一个数ans = 1 ,乘n次a,这样的时间复杂度为O(n),而快速幂算法是基于二进制,可以将时间复杂度将为log(n)

       举个例子,我们要求3^11,我们可以写成  3^(2^3+2^1+2^0),拆开后就是3^(2^3) = 3 ^ 8 、3^(2^1)=3^2 、 3^(2^0) = 3^1 , 这样看来,如果我们只计算这三个的乘积,岂不是只需要计算3次?而且这三个数之间是很有规律的,

       比如  (3^1)^2 = 3^2 , ( (3^2)^2) ^2 = 3 ^8,就是对一个数不断的取二次幂,由于任意整数都可以用二进制的数来表示,也就是说我们可以将任意整数拆解成3^(2^3+2^1+2^0)这样的形式(为了方便,我们将要求的数记作a^n) , 而对于2^k是否出现,取决于n在二进制表示下第k+1位数是否为1 。 为了更加清晰的解释,我们分析一下 11 这个数,其二进制的表示形式为 1011 , 对应出现了第4 , 2 , 1 位数,于是与之对应的2^3  , 2^1 , 2^0 也就出现了。

       上面我们解释了任意整数都可以写成  a ^ (2 ^ m + 2 ^ k .... )的形式,而且对于 m+ 1= k 的情况时,存在

  (a^(2^m)) ^ 2 = a^(2^m+1) = a^(2^k) , 再根据2^k的出现规律,我们只需要将2^k从 k = 0 开始,不断地取二次幂,如果n在二进制下的第k+1位数为1,我们用ans记录当前的值,这时候将a(2^k)乘入ans 中,最后我们就得到了最终的答案

代码区

#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;

ll pow_fast(ll a, ll n)
{
	ll ans = 1;
	while (n != 0)
	{
		if (n & 1 != 0)ans =ans*a;
		a = a * a;
		n >>= 1;
	}
	return ans;
}

int main()
{
	cout << pow_fast(2, 5) << endl;
	return 0;
}

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值