这个算法是针对求a的b次方%p的加速算法。
当我们要求a的b次方时,一般情况会使用pow或者自己循环一个一个乘,但是当b特别大,像是194532681等的大数字,并且需要对p取模时,第一种会爆,第二种会超时。这怎么办呢?
小小铺垫——搞式子
我们先看几个例子:
22×23=22+3
45×47=412
我们发现,当ab1与bb2相乘时,答案就为 ab1+b2。
接着,我们考虑怎么优化循环乘的算法,一种考虑开方b,一种考虑log(b)
开方似乎没有,我们试试log。log一般与2有很大关系,于是我们猜想:将b转化成二进制,然后求答案。
引入主题——快速幂
假设我们的指数b为28,它的二进制是11100,我们发现,如果要求a28,实际上就等价为a4+8+16。那么,我们就可以将指数拆成二进制形式,然后凡是位数是1的就加上a的几次方,就能很好优化循环超时的问题了。
代码实现——打代码
int ksm(int a,int b)
{
int u=a,s=1;//给a备份
while(b>0)//判断条件为b大于0
{
if(b&1)s=s*u%p;//分解二进制时位数为1
u=u*u%p;//累乘次方
b>>=2;//缩进一位
}
return s;//返回答案
}
完美结束——做总结
总的来说,快速幂是利用了二进制优化的思想,将本来需要执行b次的循环优化成了log(b)次的循环,大大提高了效率。