快速幂是一种减少计算机计算次数的方法
正常求幂运算,例如n`11,则需要乘11个n,即计算10次。
但是用快速幂方法可减少计算次数。
以二进制推演原理
11换算为二进制数为1011,即
所以n`11==n`(2`3*1+2`2*0+2`1*1+2`0*1)==n`(2`3*1)*n`(2`2*0)*n`(2`1*1)*n`(2`0*1)
因为2`2*0==0,n`(2`2*0)==1
所以n`11==n`(2`3*1)*n`(2`1*1)*n`(2`0*1)
所以只需计算n`(2`3*1) n`(2`1*1) n`(2`0*1)
也就是当11的第x位二进制位为1时有效,需要乘以n`(2`(x-1)*1)。
则在实现算法时,我们需要定义一个变量设为base,将每次循环的第x次,都乘以原来的base,以得到n`(2`(x-1)*1)==base。
然后再定义一个最终返回值变量result先初始化为1,判断第x位二进制位,是否为1,如果为1则乘以base,否则不变。最终实现`11==n`(2`3*1)*n`(2`1*1)*n`(2`0*1)
在判断11的第x二进制位是1或0时,可通过两种方法。
一:
定义一个变量b初始化为11(幂),每次base更新后将b/2,除以2后在下次循环中判断%2的结果是否为0,如果==1则该次循环数的二进制位为1,反之为0.
二:
定义一个变量b初始化为11(幂),利用运算符>>,将b的二进制数向右移。利用按位与操作符&,(详情看另一笔记操作符)
快速幂代码实现(这里在int部分报错是因为”快速幂“没有注释掉”)
龟速乘
同样是一种减少运算次数的方法。
例如该题,需要对e18的范围的数字相乘,若直接相乘则一定会爆出longlong。则我们可以通过一个个的相加,相加e18次,每一次相加都对其取模,则可以得出结果,但一定会超时。
这时我们就需要进行龟速乘。
与快速幂原理类似,从二进制位方面理解。例如11*6,11的二进制为1011,则11==2`3*1+2`1*1+2`0*1。所以算式可表达为,6*(2`3*1)+6*(2`1*1)+6*(2`0*1).
这样从原本的相加6次变成了相加3次。即使是很大的数也最多会相加32次(操作系统32位,数字为32位二进制数)
用代码实现a*b时(这里以b为二进制运算为例)则需要先定义一个变量result初始化为0,然后每次运算循环时判断b的该次第x位二进制位是否为1,若是,则result+=a*(2·(x-1)*1).判断加减后,则将b进行处理让其下次表现下一个二进制位,然后对a*2,获得第x位的二进制位*a的值
龟速乘函数代码实现
则我们需要迎合题目需求将int 改成long long,然后在每次运算都对变量进行一次取模,则就可以快速实现题目的要求