题意:求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=0∗20+1∗21+1∗22.
这时候
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=b0∗20+1∗21+1∗22=b2∗b4.
相信聪明的你已经看出了规律: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));
}