快速幂
它是一个可以将时间复杂度O(n)变成O(logn)的一种算法;
样例:
求12的13次方
对于指数每次除2,那么相应的底数就需要扩大2倍。那么如果指数是奇数的话怎么办,那就需要再找一个变量存起来‘多’的数。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int a,b;
cin>>a>>b;
long long sum=1;
while(b)//while(b!=0)
{
if(b%2==0)//判断b是否为偶数
{
a=a*a;//b为偶数时让底数a变为原来的二倍
}
else//b为奇数
{
sum=sum*a;//需要用一个变量‘记录’此时的a
a=a*a;//a还是需要扩大二倍
}
b=b/2;//指数缩小
}
cout<<sum;//输出即可
return 0;
//为什么直接输出sum就行了
//因为无论b是任何数,变成0之前一定会变成1,所以在变成1的时候都会有sum*=a;
//因此直接输出sum即可
}
此时的时间复杂度相较于最简单的代码来说已经降低了很多了,但是还能够更加简便
对于计算机来说,任何的数字都是转变成二进制来进行计算的,那直接使用位运算时间会变得更低。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int a,b;
cin>>a>>b;
long long sum=1;
while(b)//while(b!=0)
{
if(b&1)//if(b&1==1)
//表示对b取其二进制最右边的一位看是否为1
{
sum*=a;//为1,就对a进行累乘并存储
}
a*=a;//为下一次计算做准备
b>>=1;//指数位全部右移
//对于1011(2)来说,刚开始b&1,这个1是101(1)这个
//右移就是1011(2)变成0101(2)再进行&1的话就是最右边的1
}
cout<<sum;
return 0;
}
最后附上模板
ll ksm(ll x,ll y,ll p)
{
ll ans=1;
while(y)
{
if(y&1)
{
ans=(ans*x)%p;
}
y>>=1;
//x=ksc(x,x,p);
//如果x过大,则用该式子,会花费一点时间,需要配合快速乘使用
x=(x*x)%p;
}
return ans;
}