话说最近在学Miller_Rabin算法,顺便来提一下快速幂和快速积
快速幂和快速积利用了二分的思想
快速幂::
快速幂用字母表示为:,根据幂的运算,可以把
转换为
所以这就是快速幂的由来
递归::
简要思路
我们用来记录答案(预处理
)每次把指数
,先把
平方,然后如果
是奇数,再把
代码
int ksm(int a,int b,int n) {//a为底数,b为指数,为模数
int ans=1;//记录答案
if(b==1)
return a%n;//b=1,直接返回a
ans=(ans*(ksm(a,b/2,n)%n)*(ksm(a,b/2,n)%n))%n//平方后记住取模
if(b&1)//指数为奇数,还要多乘一个,b&1就是b%2==1的意思
ans=(ans*a)%n;
return ans;
}
递推::
简要思路
还是用来记录答案,如果
是奇数,就把
,然后再把
平方,当然每次还是要把
代码
int ksm(int a,int b,int n) {//同上
int ans=1;
while(b) {//循环
if(b&1)
ans=(ans*a)%n;//b为奇数就要乘一次
a=(a*a)%n;//底数平方一次
b>>=1;//等价于b/2
}
}
当然,因为递归需要一层一层深入再一层一层出来,所以时间复杂度相对较高
快速积
快速积和快速幂是一个道理
还是有两种方法:
递归
思路就不讲了吧,跟上面是一个道理
int ksc(int a,int b,int n) {//懒得解释了
int ans=0;
if(b==1)
return a;
ans=(ans+ksc(a,b/2,n)%n*2)%n
if(b&1)
ans=(ans+a)%n;
return ans;
}
递推
int ksc(int a,int b,int n) {
int ans=0;
while(b) {
if(b&1)
ans=(ans+a)%n;
a=a*2%n;
b>>=1;
}
}
总结
快速幂和快速积其实是非常节省时间的,如果我们直接用或者直接乘的话,时间复杂度是
,而用了快速幂和快速积后,因为是二分,时间复杂度可以降到
,在大数据面前还是很实用
其实这是作者留给自己的板