有关数论中的快速幂算法分析
法一:递归法:
int qpow(int a,int b) {
if(!b)
return 1;
else if (b & 1)
return a * qpow(a,b-1);
else {
int t = qpow(a,b>>1);
return t * t;
}
}
递归的代价太大了!
法二:快速幂
分析:
这个思维方式类似于二分法中的折半,不断使指数减半来降低复杂度。指数使偶数则折半,指数为奇数则提取出一个底数使得指数变成偶数再折半,提取出的底数与之前提取出的指数相乘成为新的余数。
例如:求3的42次方:
int qpow(int a,int b)//a为底数,b为指数
{
int ret=1;//ret为余数
while(b > 0)
{
if(b & 1)//如果是奇数(按位与)
ret *= a;
a *= a;
b>>=1;//b向右移一位(相当于除以二)
}
return ret;
}
计算过程:
例题:求解A^ B的最后三位数表示的整数
法一:一般思路
long long nPower(long long base,long long power)
{
long long result=1;
for(int i=1;i<=power;i++)
{
result=result*base;//溢出,2^100=0
}
return result%1000;
}
改进:
long long nPower(long long base,long long power)
{
long long result=1;
for(int i=1;i<=power;i++)
{
result=result*base;
result=result%1000;//范围更大,可以计算2^100=375
}
return result%1000;
}
法二:快速幂
long long fastPower(long long base, long long power)
{
long long result = 1;
while (power > 0)
{
if (power & 1)
{
result = result * base % 1000;
}
power >>= 1;
base = (base * base) % 1000;
}
return result;
}
例题二:快速幂||取余运算(重点:取余运算)
题目描述
给你三个整数 b,p,k,求 b^p mod k
输入格式
输入只有一行三个整数,分别代表 b,p,k
输出格式
输出一行一个字符串 b^p mod k=s,其中 b, p, k分别为题目给定的值, s 为运算结果。
分析:
快速幂:a自乘变成a^2, a^2 再自乘变成a^4, a4再自乘变成a8…不断自乘比一次次乘以a的速度要快。如果是偶数,b直接自乘,如果是奇数,则先乘以一个b然后再自乘。
其次,要用long long来储存b,p,k,并且每步取余来防止溢出(别忘记最后还要取余)
由上面的取余运算的公式:(ab)%p=(a%pb%p)%p
#include <bits/stdc++.h>
using namespace std;
int main(){
long long ans=1,k,b,p;
scanf("%lld%lld%lld",&b,&p,&k);
printf("%lld^%lld mod %lld=",b,p,k);
while(p>0){
if(p & 1)
ans=ans*b%k;
b=b*b%k;
p=p>>1;//向右移一位,相当于除以二
}
printf("%lld",ans%k);//别忘记最后还要取余
return 0;
}