洛谷 P1226 【模板】快速幂||取余运算

题目描述

给你三个整数 a,b,p,求 a^b mod p。

输入格式

输入只有一行三个整数,分别代表 a,b,p。

输出格式

输出一行一个字符串 a^b mod p=s,其中 a,b,p 分别为题目给定的值, s为运算结果。

思路

很久之前当我还只会循环时就尝试过这道题,结果当然是美美WA了。今天本来应该学高精除法不知道为啥又开始学快速幂。看了dalao的解析才好不容易学会。

简化的第一步:
由数学知识可得:
(a * b) % p = (a % p * b % p) % p

也就是说,一个合数的模等于它两因数分别取模相乘后再取模。一般化的结论即为,多个因子乘积的模==每个因子分别取模再相乘再取模。因子取模后当然会减小,减小乘数,进行乘法的速度就会提高。

原来只用循环的代码长这样:

while(b--){
	res*=a;
}
res%=p;

用这个公式优化后长这样:

while(b--){
		int m=a%p;
		res%=p;
		res*=m;
	}
	res%=p;

简化的第二步:

快速幂算法能帮我们算出指数非常大的幂,传统的求幂算法之所以时间复杂度非常高(为O(指数n)),就是因为当指数n非常大的时候,需要执行的循环操作次数也非常大。所以我们快速幂算法的核心思想就是每一步都把指数分成两半,而相应的底数做平方运算。这样不仅能把非常大的指数给不断变小,所需要执行的循环次数也变小,而最后表示的结果却一直不会变。
原文链接:https://blog.youkuaiyun.com/qq_19782019/article/details/85621386

求快速幂过程可以简化为这样的递归算法:
若b%2==0&&b!=2  -->return a^(b/2)*a^(b/2)

若b%2==1 -->return a*a^(b-1)

若b==0 --> return 1

代码如下:

while(b){
    	if(b%2==0){
    		b/=2;
    		a*=a;
    		a%=p;
		}else{
			b/=2;
			res*=a;
			res%=p;
			a*=a;
			a%=p;
		}
	}

简化的第三步:

由于计算机内部实际上是把+ - * / 转化为位运算来进行计算的,所以如果我们在代码中直接使用位运算的话速度会更快。

位运算的一些基本知识:

 显然,用位运算我们可以完成判断奇偶性的操作:若判断数字为奇数,则其二进制末位为1。与1进行与运算后结果为1。同样,偶数和1进行与运算后结果为0.

b/=2的操作也可以使用位运算。原理和分解十位整数的原理相近:设a为十进制数,“砍掉”末位相当于给a整除10 。

那么对于二进制数,如果想对它进行除二操作,“砍掉”它的最后一位,即将每一个数字全部右移一位。

代码如下:

while(b){
    	if(b&1==0){//相当于当b为偶数时 
    		b>>=1;
    		a*=a;
    		a%=p;
		}else{
			b>>=1;
			res*=a;
			res%=p;
			a*=a;
			a%=p;
		}
	}

完整代码:

#include<stdio.h>
typedef long long ll;
int main(){
	ll a,b,p;
	ll b1;
	scanf("%lld %lld %lld",&a,&b,&p);
	b1=b;
	ll res=1;
	ll a1=a;
	while(b){
    	if(b&1==0){//相当于当b为偶数时 
    		b>>=1;
    		a*=a;
    		a%=p;
		}else{
			b>>=1;
			res*=a;
			res%=p;
			a*=a;
			a%=p;
		}
	}
	printf("%lld^%lld mod %lld=%lld",a1,b1,p,res%p);
	return 0;
}

### 回答1: 快速幂是一种用于快速计算幂运算算法,其基本思想是将指数进行二进制拆分,然后利用指数的二进制表示来快速计算幂运算。在计算过程中,可以利用运算来避免数值溢出,提高计算效率。快速幂算法的时间复杂度为O(logn)。 具体实现时,可以使用递归或循环的方式来实现快速幂算法。在递归实现中,需要注意处理指数为负数的情况。在循环实现中,需要注意处理指数为0的情况。 运算可以使用%运算符来实现,其含义是求两个数相除的数。在快速幂算法中,运算可以避免数值溢出,提高计算效率。需要注意的是,在运算中,除数不能为0。 综上所述,快速幂算法运算是计算幂运算时常用的算法运算符,能够提高计算效率,避免数值溢出。 ### 回答2: 快速幂算法是一种优化指数运算算法,通常用于对大整数进行多次乘方运算。该算法的基本思想是将指数拆分成二进制的形式,然后利用指数的二进制表示逐步计算。 具体来说,假设要计算a^b mod c的值,其中a、b、c均为正整数,那么可以先将b转换为二进制的形式,然后从右往左遍历这个二进制数,每次将当前位的值乘到结果中,同时对结果模,然后将底数a自乘一次,且也要对结果模。最终得到的结果就是a^b mod c的值。 例如,假设要计算3^13 mod 7的值,将13转换为二进制的形式得到1101,从右往左遍历这个二进制数,开始时结果为1,底数为3,当前位是1,那么将3乘到结果中,并对结果模得到3,底数自乘得到9 mod 7 = 2;下一位是0,直接将底数自乘,即2*2 mod 7 = 4;再下一位是1,将底数自乘得到16 mod 7 = 2,同时将2乘入结果,结果为3×2 mod 7 = 6;最后一位是1,将底数自乘得到4 mod 7 = 4,同时将4乘入结果,结果为6×4 mod 7 = 3,因此3^13 mod 7的值为3。 快速幂算法的优点是可以快速地计算指数运算,具有较好的时间复杂度。同时,运算的存在可以避免产生过多的中间结果,节省了空间复杂度。然而,快速幂算法的缺点是需要将指数转换为二进制形式,这可能会增加算法的编程难度。 ### 回答3: 快速幂是一种用于求解幂运算的快速算法。在进行运算时,快速幂算法能够通过对结果模,使得计算结果更为精确。在计算大数据的幂的运算时,常常可以使用快速幂算法来进行加速运算快速幂算法可以使用递归的方式实现,也可以使用循环的方式实现。递归实现的代码比较简单,但是存在栈空间过大的问题;循环实现的代码虽然有一定的难度,但是能够避免栈空间过大的问题。 在进行运算时,我们需要注意的是,如果运算的两个数都很大,那么我们在计算结果时需要特别小心。因为如果直接进行计算,可能会导致数据类型溢出,进而产生错误的结果。为了避免这种情况,我们可以在进行计算时,对结果进行模处理。 在进行运算时,我们需要使用模定理,也就是(a*b)%p=(a%p)*(b%p)%p。通过这种方式,可以使得计算结果更为精确,也可以避免数据类型溢出的情况发生。如果无法使用模定理,则需要使用高精度的算法进行运算。 总而言之,快速幂算法是一种非常有效的幂运算算法,可以快速地计算出大数据的幂运算结果。在进行运算时,需要特别注意数据类型溢出的问题,在进行计算时需要特别小心。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值