快速幂算法分析

有关数论中的快速幂算法分析

在这里插入图片描述
法一:递归法:在这里插入图片描述

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值