矩阵模板
重载输入流 输出流 + *
矩阵快速幂 求逆矩阵
逆矩阵求法往下滑…
struct matrix{
vector<vector<ll>>a;
int n,m;
matrix(int n,int m){
this->n=n,this->m=m;
a=vector<vector<ll>>(n+1,vector<ll>(m+1,0));
}
matrix(int n,int m,char x){
//单位阵
this->n=n,this->m=m;
a=vector<vector<ll>>(n+1,vector<ll>(m+1,0));
for(int i=1;i<=min(n,m);i++)a[i][i]=1;
}
friend istream &operator>>(istream &input,matrix &B){
for(int i=1;i<=B.n;i++){
for(int j=1;j<=B.m;j++){
input>>(B.a[i][j]);
}
}
return input;
}
friend ostream &operator<<(ostream &output,const matrix &B){
for(int i=1;i<=B.n;i++){
for(int j=1;j<=B.m;j++){
output<<B.a[i][j]<<' ';
}
output<<'\n';
}
return output;
}
matrix operator + (const matrix &B){
matrix sum(n,m);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
sum.a[i][j]=this->a[i][j]+B.a[i][j];
sum.a[i][j]%=mod;
}
}
return sum;
}
matrix operator * (const matrix& B){
matrix mul(n,B.m);
for(int i=1;i<=n;i++){
for(int j=1;j<=B.m;j++){
for(int k=1;k<=m;k++){
mul.a[i][j]+=this->a[i][k]*B.a[k][j];
mul.a[i][j]%=mod;
}
}
}
return mul;
}
matrix pow(int k){//矩阵快速幂
matrix ans(n,m,'E'),base=*this;
while(k){
if(k&1)ans=ans*base;
base=base*base;
k>>=1;
}
return ans;
}
matrix inreverse(){//求逆矩阵
matrix tmp=*this,ans(n,m,'E');
for(int i=1;i<=n;i++){
int maxn=i;
for(int j=i+1;j<=n;j++){
if(tmp.a[j][i]>tmp.a[maxn][i])maxn=j;
}
swap(tmp.a[i],tmp.a[maxn]);
swap(ans.a[i],ans.a[maxn]);
if(tmp.a[i][i]==0)return matrix(0,0);//不存在
for(int j=1;j<=n;j++){
if(j==i)continue;
ll base=tmp.a[j][i]*ksm(tmp.a[i][i],mod-2)%mod;
for(int k=n;k>=1;k--){
ans.a[j][k]-=ans.a[i][k]*base%mod;
ans.a[j][k]=(ans.a[j][k]%mod+mod)%mod;
tmp.a[j][k]-=tmp.a[i][k]*base%mod;
tmp.a[j][k]=(tmp.a[j][k]%mod+mod)%mod;
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
ans.a[i][j]*=ksm(tmp.a[i][i],mod-2);
ans.a[i][j]%=mod;
}
}
return ans;
}
};
逆矩阵的求解
A = [ a 11 a 12 ⋯ a 1 n a 21 a 22 ⋯ a 2 n ⋮ ⋮ ⋱ ⋮ a m 1 a m 2 ⋯ a m n ] . A = \begin{bmatrix} a_{1 1} & a_{1 2} & \cdots & a_{1 n} \\ a_{2 1} & a_{2 2} & \cdots & a_{2 n} \\ \vdots & \vdots & \ddots & \vdots \\ a_{m 1} & a_{m 2} & \cdots & a_{m n} \end{bmatrix} \text{.} A= a11a21⋮am1a12a22⋮am2⋯⋯⋱⋯a1na2n⋮amn .
比如A这个矩阵
只需要往右边补一个单位阵
即为
T = [ a 11 a 12 ⋯ a 1 n 1 0 ⋯ 0 a 21 a 22 ⋯ a 2 n 0 1 ⋯ 0 ⋮ ⋮ ⋱ ⋮ ⋮ ⋮ ⋱ ⋮ a m 1 a m 2 ⋯ a m n 0 0 ⋯ 1 ] . T = \begin{bmatrix} a_{1 1} & a_{1 2} & \cdots & a_{1 n} & 1 & 0 & \cdots & 0\\ a_{2 1} & a_{2 2} & \cdots & a_{2 n} & 0 & 1 & \cdots & 0 \\ \vdots & \vdots & \ddots & \vdots & \vdots & \vdots & \ddots & \vdots \\ a_{m 1} & a_{m 2} & \cdots & a_{m n} & 0 & 0 & \cdots & 1 \end{bmatrix} \text{.} T= a11a21⋮am1a12a22⋮am2⋯⋯⋱⋯a1na2n⋮amn10⋮001⋮0⋯⋯⋱⋯00⋮1 .
然后只需要对矩阵进行初等变换
使得拼接的前半部分变为单位阵 此时右半部分的矩阵即为 A − 1 A^{-1} A−1
正确性证明:
设左半矩阵为 A A A,右半矩阵为单位阵 E E E
初等行变换 即为 P A = E PA=E PA=E
则 A − 1 = P A^{-1}=P A−1=P
而右半矩阵经过同等的初等行变换后即变为 P E = P = A − 1 PE=P=A^{-1} PE=P=A−1
得证