乘方快速幂

乘方快速幂,是为了解决a^b次方普通计算方法太慢的问题。算法

计算a的b次方,普通的for循环求法以下(O(n)):ide

1 int a(int x,int n)
2 {
3     int t=1;
4     for(int i=1;i<=n;i++)
5     {
6         t=t*x;
7     }
8     return t;
9 }
View Code

递归求法:函数

1 int Pow(int a,int b)
2 {
3     if(b==0)
4         return  1;
5     else
6         return Pow(a,b-1)*a;
7 }
View Code

二分(递归)求法:ui

1 int pow(int a,int b)
2 {
3     if(b==0)
4         return 1;
5     if(b%2==0)
6         return pow(a*a,b/2);
7     return a*pow(a*a,b/2);
8 }        
View Code

固然,数学函数pow(a,b)一步解决问题。可是,由于对时间的要求,有些算法每每时间效率不高,而乘方快速幂也是(O(logn))的解法。spa

首先,3的26次方,咱们能够发现它彻底不须要一次一次的乘,由于26次方==2^1+2^3+2^4=2+8+16code

因此3^26 = 3^2 *3^8 * 3^16,而3^2=(3^1)^2,(3^4)=(3^2)^2,3^8=(3^4)^2,因此O(logn)的时间可求出3^2,blog

3^4,3^8...固然,若是指数很大的话,咱们很差一点一点分析如何差解,因此咱们拿指数的二进制入手。递归

如26的二进制表示为11010,1对应的权值为16,8,2。它们表示的含义即为对应的乘方次幂是须要的。固然这种分发不惟一的,你也能够分红8,8,4,4,2。可是为了计算方便和应对指数幂很大的状况,根据二进制位是1来划分是最高效的。get

对应的算法以下:数学

 1 long long  Quick_Pow(long long  a,long long  b)
 2     {
 3         long long  ans = 1;
 4         while(b)//指数不为0
 5         {
 6             if(b & 1)//b为奇数,即二进制最右边一位为1时,说明须要乘这个数
 7                  ans = ans * a ;
 8             a = a*a ;//不然底数自乘积
 9             b >>= 2;//右移1位
10         }
11         return ans;
12     }
View Code

能够简单检验运行结果。

固然,当结果很大的时候,或要求对答案进行取模处理,这只须要在代码中简单处理便可。

 1 long long  Quick_Pow(long long  a,long long  b,long long mod)
 2     {
 3         long long  ans = 1;
 4         while(b)
 5         {
 6             if(b & 1)
 7                  ans = ans * a % mod ;
 8             a = a*a % mod ;
 9             b >>= 2;
10         }
11         return ans;
12     }
View Code

 题目连接:

Raising Modulo Numbers 、 Pseudoprime numbers

相关文章
相关标签/搜索