【学习】矩阵
(学习)矩阵乘法
1. 矩阵的本质就是线性方程式,两者是一一对应关系
2. 十个利用矩阵乘法解决的经典题目 http://www.matrix67.com/blog/archives/276
3. 矩阵构造方法 https://blog.csdn.net/weixin_39212776/article/details/78836835
4. 矩阵乘法题集 https://blog.csdn.net/qq_34416123/article/details/83047013
矩阵加速
#include<bits/stdc++.h>
#define ll long long
#define For(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
int T,n;
const int p=1e9+7;
struct mat{
ll m[5][5];
}ans,base;
inline mat mul(mat a,mat b){//等我学会重载运算符我就来改!quq
mat res;
memset(res.m,0,sizeof(res.m));
For(i,1,3){
For(j,1,3){
For(k,1,3){
res.m[i][j]+=(a.m[i][k]%p)*(b.m[k][j]%p);
res.m[i][j]%=p;
}
}
}
return res;
}
inline void sets(){
memset(ans.m,0,sizeof(ans.m));
For(i,1,3) ans.m[i][i]=1;
memset(base.m,0,sizeof(base.m));
base.m[1][1]=base.m[1][3]=base.m[2][1]=base.m[3][2]=1;
}
inline void matksm(){
while(n){
if(n&1) ans=mul(ans,base);
base=mul(base,base);
n>>=1;
}
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d",&n);
if(n<=3){printf("1\n");continue;}
sets();
matksm();
printf("%lld\n",ans.m[2][1]);
}
return 0;
}
矩阵乘法
- 两个矩阵相乘的前提是前一个矩阵的列数等于后一个矩阵的行数
- 单位矩阵:
-对于n∗m的矩阵,它的单位矩阵大小为m∗m;对于m∗n的矩阵,它的单位矩阵大小为n∗n
-单位矩阵的元素非0即1,从左上角到右下角的对角线上元素皆为1,其他皆为0
- 代码:
#include<bits/stdc++.h>
#define ll long long
#define For(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
const int M=105,p=1e9+7;
ll n,k;
inline ll read(){
ll f=1,sum=0;
char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){sum=(sum<<1)+(sum<<3)+(ch^48);ch=getchar();}
return f*sum;
}
struct node{
ll a[M][M];
node(){
memset(a,0,sizeof(a));
}
inline void build(){For(i,1,n)a[i][i]=1;}
}mat,ans;
node operator *(const node &x,const node &y){//重载运算符
node z;
For(k,1,n){
For(i,1,n){
For(j,1,n){
z.a[i][j]=(z.a[i][j]+x.a[i][k]*y.a[k][j]%p)%p;
}
}
}
return z;
}
inline void matksm(){
while(k){
if(k&1) ans=ans*mat;
mat=mat*mat;
k>>=1;
}
}
int main(){
n=read(),k=read();
For(i,1,n){
For(j,1,n){
mat.a[i][j]=read();
}
}
ans.build();
matksm();//与普通快速幂无异,只是不能写成*=
For(i,1,n){
For(j,1,n){
printf("%d ",ans.a[i][j]);
}
printf("\n");
}
return 0;
}