快速幂是很常见的一种高效算法,他有几个变体,下面记录一下。
特别注意,下面的快速幂和矩阵快速幂中,都要根据题目,处理好0^0的状态,不然都会得到1或者单位矩阵。
首先是标准的快速幂。
int Qpow(int a, int b, int mo)
{
if(a % mo == 0) return 0; //处理0^0的情况
int ans = 1;
a %= mo; //控制a的大小
while(b)
{
if(b & 1) ans = ans * a % mo;
a = a * a % mo;
b >>= 1;
}
return ans;
}
既然快速幂可以解决乘方运算的溢出问题,那么就有快速乘解决乘法运算的溢出问题。其实主要就是把乘法变成加法。
int Qmul(int a, int b, int mo)
{
int ans = 0; //这里和快速幂不同,要注意
a %= mo; //控制大小
b %= mo;
while(b)
{
if(b & 1) ans = (ans + a) % mo;
a = (a << 1) % mo;
b >>= 1;
}
return ans;
}
除此之外,快速幂还可以用于矩阵,即矩阵快速幂。若一个矩阵要用快速幂,显然这是一个方阵。
//进行矩阵乘法
void Matrix(int a[maxn][maxn], int b[maxn][maxn], int mo)
{
int temp[maxn][maxn];
MS(temp, 0);
FOR(i, 1, n) FOR(j, 1, n) FOR(k, 1, n) //n为矩阵实际大小
{
temp[i][j] = (temp[i][j] + a[i][k] * b[k][j]) % mo;
}
memcpy(a, temp, sizeof(temp));
}
//进行矩阵快速幂
void Qmatrix(int A[maxn][maxn], int b, int mo)
{
int ans[maxn][maxn];
MS(ans, 0);
FOR(i, 1, n) ans[i][i] = 1; //n为矩阵实际大小,ans为单位矩阵
while(b)
{
if(b & 1) Matrix(ans, A, mo); //ans*A且把值赋给ans
Matrix(A, A, mo);
b >>= 1;
}
memcpy(A, ans, sizeof(A)); //答案赋给A
}