思想:二分,时间复杂度O(log n)
例 : 普通计算2 的 10 次幂 2*2*2*2....*2是O(n)时间复杂度
快速幂 通过平方求幂,
2的平方得 2的2次幂
2的2次幂 再平方 得2的四次幂
2的四次幂 再 乘2 得 2的五次幂
然后2的五次幂再平方得2的10次幂
得递归表达式:
当n为偶数, 计算2的n/2次幂 再相乘
n为奇数 计算2的n-1次幂 再乘2
n为0 答案为1
递归写法:
#include <iostream>
using namespace std;
//int k=7;
int ebs(int x,int n)
{
if(n==0)
{
return 1;
}
else if(n%2==1)
{
return ebs(x,n-1)*x;
}
else
{
int tmp=ebs(x,n/2); //不能写成ebs(x,n/2)*ebs(x,n/2) 否则计算两次ebs(x,n/2)
return tmp*tmp; //时间复杂度变为O(n)
}
}
int main ()
{
int n,m; 计算n的m次幂
cin>>n>>m;
int res=ebs(n,m);
cout<<res;
return 0;
}
当需要取模时只要再原代码中略微修改,步步取模即可
#include <iostream>
using namespace std;
int k=7; //此处结果对7取模
int ebs(int x,int n)
{
if(n==0)
{
return 1;
}
else if(n%2==1)
{
return ebs(x,n-1)*x%k;
}
else
{
int tmp=ebs(x,n/2)%k;
return tmp*tmp%k;
}
}
int main ()
{
int n,m;
cin>>n>>m;
int res=ebs(n,m);
cout<<res;
return 0;
}
补充:非递归写法
#include <iostream>
using namespace std;
int main ()
{
int n,p; //计算n的p次幂
cin>>n>>p;
int res=1;
while(p)
{
if(p%2==1)res=res*n;
n=n*n;
p/=2;
}
cout<<res;
return 0;
}
取模:
#include <iostream>
using namespace std;
int k=7; //对7取模
int main ()
{
int n,p;
cin>>n>>p;
int res=1;
while(p)
{
if(p%2==1)res=res*n%k;
n=n*n%k;
p/=2;
}
cout<<res;
return 0;
}