(主要是写给自己看,加深理解顺便记录)
求 a 的 b 次方对 p 取模的值
输入格式
三个整数 a,b,p ,在同一行用空格隔开。
输出格式
输出一个整数,表示a^b mod p的值。
数据范围
1≤a,b,p≤10^9
时/空限制: 1s / 32MB
输入样例:
3 2 7
输出样例:
2
解题思路:
1、取模运算的性质:(ab)%p=[(a%p) * (b%p)]%p
证明:
设a = k1 * p + q1 , b = k2 * p + q2
a * b = ( k1 * k2 * p + k1 * q2 + k2 * q1 ) * p + q1 * q2
所以 ( a * b ) % p = ( q1 * q2 ) % p
有 a % p = q1 , b % p = q2
2、例如计算3^10:
3^10 = ( 3^2 )^5 = 9^5 = 9 * ( 9^2 )^2
指数分奇偶情况
代码实现:
typedef long long ll;
ll power(ll a,ll b,ll p){
ll ans=1%p;//若p=1,则1%1=0
a%=p;
while(b){
if(b%2==1) ans=(ans*a)%p;
a=(a*a)%p;
b/=2;
}
return ans;
}
改良版代码
typedef long long ll;
ll power(ll a,ll b,ll p){
ll ans=1%p;
a%=p;
while(b){
if(b&1) ans=(ans*a)%p;//判断该二进制位是否为1,即次数是否是奇数
a=(a*a)%p;
b>>=1;//位移操作
}
return ans;
}
64位整数乘法
类比快速幂
例如讲一个数转化成二进制
11=(1011)=1* 2^3 + 0* 2^2 + 1 * 2^1+1 * 2^0
将b转化为二进制加法表示,再分别与a相乘,最后相加。
扫描二维码关注公众号,回复:
12648397 查看本文章

typedef long long ll;
ll power(ll a,ll b,ll p){
ll ans=0;
a%=p;
while(b){
if(b&1) ans=(ans+a)%p;
a=(a*2)%p;
b>>=1;
}
return ans;
}