矩阵快速幂
矩阵快速幂,就是矩阵乘法和快速幂的结合,所以在讲矩阵快速幂之前,先讲讲矩阵乘法和快速幂。
1. 矩阵
1.1 矩阵的定义
什么是矩阵?由
被称为
这个矩阵中的
行矩阵(行向量): 只有一行的矩阵。
列矩阵(列向量): 只有一列的矩阵。
同型矩阵: 两个矩阵
单位矩阵: 在矩阵乘法中起着很大的作用,相当于乘法中的
1.2 矩阵加法
我们定义两个m
注意:
- 矩阵加法满足交换律和结合律
- 只有两个同型矩阵才可以做加法
1.3 矩阵乘法
我们定义两个矩阵
并将此计做
注意: 矩阵乘法不满足交换律。
如果还不理解的话可以看这里
用代码写出来就是下面这个亚子:
struct matrix
{
int n,m;//n是行数,m是列数
ll e[105][105];
}a;
matrix mul(matrix a,matrix b)
{
matrix ans;
ans.n=a.n;
ans.m=b.m;
for(int i=1;i<=ans.n;i++)
for(int j=1;j<=ans.m;j++)
ans.e[i][j]=0;//初始化
for(int i=1;i<=a.n;i++)
for(int j=1;j<=b.m;j++)
for(int k=1;k<=a.m;k++)
ans.e[i][j]=(ans.e[i][j]+(a.e[i][k]*b.e[k][j])%mod)%mod;//矩阵乘法结果可能很大,所以要取模
return ans;
}
2. 快速幂
一般我们求
代码实现长这个亚子:
long long power(long a,long b,long c)
{
long long ans=1;
while(b)//没有枚举完
{
if(b&1) ans=(ans*a)%c;//这一位是否是1
a=(a*a)%c;
b>>=1;//走到下一位
}
return ans%c;
}
3. 矩阵快速幂
讲完了上面这些,那矩阵快速幂就很好理解了!就是把运算改成矩阵运算。
首先,
代码实现:
struct matrix
{
int n,m;
ll e[105][105];
}a;
matrix mul(matrix a,matrix b)
{
matrix ans;
ans.n=a.n;
ans.m=b.m;
for(int i=1;i<=ans.n;i++)
for(int j=1;j<=ans.m;j++)
ans.e[i][j]=0;
for(int i=1;i<=a.n;i++)
for(int j=1;j<=b.m;j++)
for(int k=1;k<=a.m;k++)
ans.e[i][j]=(ans.e[i][j]+(a.e[i][k]*b.e[k][j])%mod)%mod;//快速幂的取模就在这里了!
return ans;
}//代码和上面的区别
matrix power(matrix a,ll b)
{
matrix ans;
ans.n=a.n;
ans.m=a.m;
for(int i=1;i<=ans.n;i++)
for(int j=1;j<=ans.m;j++)
if(i==j) ans.e[i][j]=1;
else ans.e[i][j]=0;//初始化为单元矩阵
while(b)
{
if(b&1) ans=mul(ans,a);//要把乘换成矩阵乘法哦!
a=mul(a,a);//这里也一样呢
b>>=1;
}//快速幂板子
return ans;
}
顺便挂上矩阵加速的友链