2019/8/2 快速幂
快速幂
快速幂,顾名思义,简单直白地理解就是使用比较快速的方法计算幂。
“快速幂就是快速算底数的n次幂。其时间复杂度为 O(log₂N), 与朴素的O(N)相比效率有了极大的提高。”------百度百科
在<cmath>头文件中有这样一个函数:pow(base,exp),用于计算幂baseexp,但由于时间耗费过大,在OI中一般不会使用,而是使用时间开销较少的快速幂
前置知识:
-
位运算
-
模运算
-
二进制与十进制间转换
原理:
1.任意10进制数字都可以用1与0通过2进制表示
eg. (17)10--->16+1--->24+20--->(10001)2
2.分治思想
将较大幂转化成许多较小幂计算。
3.拆分
将幂转化为2进制,拆分为basen x basem x ······ x basek的形式计算。(n,m,k均为2i的形式)
2.实现
代码:
1 int spow( long long x, long long k,long long c)//参数: x:底数,k:指数,c:指定的模数 2 { 3 long long ans=1;//初始化答案//不能为0。 4 for (;k;k>>=1,x=x%c*x%c)if(k&1)ans=ans*x%c;//将指数分解,通过k&1判断(k)2最后一位是否为一,并将底数继续平方或乘以ans,继续将指数k右移分解//同时在这一过程中对c取模 5 return ans;//返回答案 6 }
注意:
由于<cmath>头文件中定义了STL幂函数pow(),所以在包含有此头文件的情况下函数名不能为pow()。