点击查看代码
#include<cstdio>
#pragma warning(disable:4996)
typedef long long LL; //long long型别名为LL
//求解a^b%m
//1、基础方法
//要求:a<10^9,b<10^6,1<m<10^9,时间复杂度O(b)。为了防止相乘时超出int型范围要用long long型
LL pow(LL a, LL b, LL m) {
LL ans = 1;
for (int i = 0; i < b; i++) {
ans = ans * a % m;
}
return ans;
}
//2、快速幂递归方法(b<10^18),时间复杂度O(logb)
//如果b是奇数,则a^b=a*a^(b-1)。 如果b是偶数,则a^b=a^(b/2)*a^(b/2),使用递归方法不断分解b,直到b=0时,返回a=1
//将判断b为奇数的条件b%2==1用b&1代替,速度更快。b&1是将b的末位和“1”进行位与操作,当b是奇数时末位为1,位与结果为true
LL binaryPow(LL a, LL b, LL m) {
if (b == 0)
return 1; //b为0时,返回a=1
if (b & 1)
return a * binaryPow(a, b - 1, m) % m; //b为奇数时,a*a^(b-1)%m
else {
LL mul = binaryPow(a, b / 2, m); //b为偶数时,先求a^(b/2),存入mul中
return mul * mul % m; //再求mul*mul%m
}
}
//3、快速幂迭代方法(b<10^18),时间复杂度O(logb)
LL binaryPow(LL a, LL b, LL m) {
LL ans = 1;
while (b > 0) {
if (b & 1) { //b为奇数,累计ans
ans = ans * a % m;
}
a = a * a % m; //a平方
b >>= 1; //将b右移一位(即除以2),b = b>>1
}
return ans;
}