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

题意:求b的p次幂对k取余的结果
分析:先不考虑取余的情况,我们来求b的p次
传统思想上我们认为b的p次就是由p个b相乘得到的,所以就用一层for循环便可得到答案。如果用for循环你会惊奇的发现你TLE了。这时候快速幂的好处就体现出来了。
首先应该知道的是任何数都能用二进制表示出来。
对于一个p我们可以用二进制表示出来。假设p=6 他用二进制表示出来是110. 按权值展开就是
  p = 0 ∗ 2 0 + 1 ∗ 2 1 + 1 ∗ 2 2   . \ p = 0*2^{0}+1*2^{1}+1*2^{2}\,.  p=020+121+122.
这时候
  b p = b 0 ∗ 2 0 + 1 ∗ 2 1 + 1 ∗ 2 2 = b 2 ∗ b 4   . \ b^{p} =b^{0*2^{0}+1*2^{1}+1*2^{2}}=b^{2}*b^{4}\,.  bp=b020+121+122=b2b4.
相信聪明的你已经看出了规律:b的p次可以用b的2的整数次幂的乘积表示,对于b的6次我们只要计算到b的4次就行了。然后根据p的二进制形式,哪位上有1结果就成该位对应的权值即可.
对于取余,首先得知道在过程中取余不会对结果造成影响。所以只要乘的时候每次取一次就好了,不然会溢出。
下面附上代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long int
ll b,p,k;
ll quick_mod(ll a,ll b){
	ll ans=1;
	while(b){
		if(b&1){//判断最后一位是不是1 
			ans*=a;ans%=k;
		}
		b>>=1;//右移一位
		a*=a;a%=k; 
	}
	return ans%k;
}
int main(){
	scanf("%lld%lld%lld",&b,&p,&k);
	printf("%lld^%lld mod %lld=%lld\n",b,p,k,quick_mod(b,p));
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值