例题:洛谷 P1226
思路一:
暴力乘,当然过不了。。。。
思路二:递归快速幂
当n为奇数时,不难发现a的n次方等于a的n-1次方乘以n,n为偶数时则为a的2分之n乘以2,当n为0时则为1,利用这样的性质我们会发现大大降低算法的时间复杂度,由之前的o(n)简化为o(logn)。
代码如下:
#include<bits/stdc++.h>
using namespace std;
long long a,b,c;
long long spow(long long m,long long n)//取模是因为计算过程可能爆long long
{
if(n==0)
{
return 1%c;
}
else if(n%2==1)
{
return (m%c)*(spow(m,n-1)%c)%c;
}
else
{
int temp=spow(m,n/2)%c;
return (temp%c*temp%c)%c;
}
}
int main()
{
cin>>a>>b>>c;
long long aa=a,bb=b;
printf("%lld^%lld mod %lld=%lld",aa,bb,c,spow(a,b));
return 0;
}
思路二:
非递归快速幂
例如,其中的7以由二进制表示为(0111),即是0100+0010+0001,则可以理解为。那我们该如何判断二进制表示下是否他的每位是否为1呢,那么就可以运用到我们的位运算。
代码如下:
#include<bits/stdc++.h>
using namespace std;
long long a,b,c;
int main()
{
cin>>a>>b>>c;
long long res=1;
long long aa=a,bb=b;
while(b)
{
//避免爆long long 因此每一步%c.
if(b&1)//判断是否二进制表示下最后一位为1,也可以用b%2替换
{
res=(res%c)*(a%c)%c;
}
a=(a%c)*(a%c)%c;
b>>=1;//等价与b/=2;
}
printf("%lld^%lld mod %lld=%lld",aa,bb,c,res);
return 0;
}
好了本蒟蒻的第一篇博客就写完了。