下面先贴上学长教的快速幂模板:
typedef long long ll; ll qpow(ll a,ll b,ll mod) { ll ans=1; a%=mod; while(b>0) { if(b & 1) { ans=(ans*a)%mod; } a=(a*a)%mod; b>>=1; } return ans; }那么这个快速幂是如何实现的呢?
原理就是将a^b拆分掉,拆分成若干部分,每一部分a的指数都是2的n次方的格式,下面是一个例子: 就像这样指数b被拆分成了三个部分,被拆分的三个部分对应了二进制的13(1101)的三个1,由此我们得知,可以对指数b进行相应的位运算判断和实时更新a来计算a的b次方,下面是对于代码的解释:
在qpow函数中定义了ans并赋给其初值1,用它来表示最终答案,然后进入while循环,首先进行按位与操作,这一步操作的目的是看看二进制的b的最低位是否为1,若为1代表被拆分成的各个部分中有这一部分,那就让ans乘上此时的a,完事之后要更新a的值,以和此时遍历到的b的位匹配上,如何更新?只要让a*a即可,打个比方,遍历到b的最低位时,a就是a的2的0次方,也就是它本身,b的最低为不为0,那就让ans乘上现在的a,更新a,并让b右移1位来舍弃b的最低位(因为已经用完它了);当遍历到b的次低位时,此时a的值是a的2的1次方(在上一步计算完ans后a更新了),但此时b的次低位的值是0,因此这一轮ans不更新,但是a还要更新,因为马上就要遍历到b的倒数第三位了,a的值要与之匹配,然后b再右移一位舍弃掉次高位,往后一直重复这样的操作,直到b变为0,也就是不能再分了为止,最后跳出循环并将最终结果ans返回。
可以拿这一个题练练手:链接