实战
将矩阵乘法封装在结构体里炒鸡好用
矩阵A×B
给定两个相容的矩阵A和B,即A的列数与B的行数相等,如果A= (aik)是一个mXn的矩阵,并且B=(bkj)是一个nXp矩阵,那么它们的积C=AB是一个mXp矩阵C=(cij)
其中,对于i=1,2,...,m j=1,2,...,p'
nXm矩阵A乘mXp矩阵B
for(int i=1;i<=n;++i) for(int j=1;j<=p;++j) for(int k=1;k<=m;++k) c[i][j]+=a[i][k]*b[k][j];
Fibonacci第n项
f[i]=1Xf[i-1]+1Xf[i-2] f[i-1]=1Xf[i-1]+0Xf[i-2]得到.......
#include<bits/stdc++.h>
#define ll long long const int N=100+5,M=100+5,P=1000000007,INF=1e9+7,inf=0x3f3f3f3f; ll n,m; template <class t>void rd(t &x){ x=0;int w=0;char ch=0; while(!isdigit(ch)) w|=ch=='-',ch=getchar(); while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); x=w?-x:x; } struct Maxtrix{ int a[3][3]; Maxtrix(){memset(a,0,sizeof(a));} Maxtrix operator*(const Maxtrix &b)const{ Maxtrix res; for(int i=1;i<=2;++i) for(int j=1;j<=2;++j) for(int k=1;k<=2;++k) res.a[i][j]=(res.a[i][j]+(ll)a[i][k]*b.a[k][j])%P; return res; } }ans,base; void qmul(ll b){ while(b){ if(b&1) ans=ans*base; base=base*base,b>>=1; } } int main(){ // freopen("in2.txt","r",stdin); rd(n); if(n<=2) return puts("1"),0; base.a[1][1]=base.a[1][2]=base.a[2][1]=1; ans.a[1][1]=ans.a[1][2]=1; qmul(n-2); printf("%d",ans.a[1][1]); return 0; }
Fibonacci前n项和
#include<bits/stdc++.h> using namespace std; #define ll long long const int N=100+5,M=100+5,P=1000000007,INF=1e9+7,inf=0x3f3f3f3f; ll n,m; template <class t>void rd(t &x){ x=0;int w=0;char ch=0; while(!isdigit(ch)) w|=ch=='-',ch=getchar(); while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); x=w?-x:x; } struct Maxtrix{ ll a[4][4]; Maxtrix(){memset(a,0,sizeof(a));} Maxtrix operator*(const Maxtrix &b)const{ Maxtrix res; for(int i=1;i<=3;++i) for(int j=1;j<=3;++j) for(int k=1;k<=3;++k) res.a[i][j]=(res.a[i][j]+(ll)a[i][k]*b.a[k][j])%m; return res; } }ans,base; void qmul(ll b){ while(b){ if(b&1) ans=ans*base; base=base*base,b>>=1; } } int main(){ // freopen("in2.txt","r",stdin); rd(n),rd(m); if(n==1) return puts("1"),0; if(n==2) return puts("2"),0; base.a[1][1]=base.a[2][1]=base.a[2][2]=base.a[2][3]=base.a[3][2]=1; ans.a[1][1]=ans.a[1][2]=ans.a[1][3]=1; qmul(n-1); printf("%lld",ans.a[1][1]); return 0; }
佳佳的Fibonacci
求T(n)=1×f[1]+2×f[2]+...+n×f[n]
emmmm这三道题都一个套路 推出递推公式 然后用矩阵快速幂做
#includeM=<bits/stdc++.h> using namespace std; #define ll long long const int N=5,M=100+5,P=1e8,INF=1e9+7,inf=0x3f3f3f3f; ll n,m; template <class t>void rd(t &x){ x=0;int w=0;char ch=0; while(!isdigit(ch)) w|=ch=='-',ch=getchar(); while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); x=w?-x:x; } struct Maxtrix{ int a[N][N]; Maxtrix(){memset(a,0,sizeof(a));} Maxtrix operator*(const Maxtrix &b)const{ Maxtrix c; for(int i=1;i<N;++i) for(int j=1;j<N;++j) for(int k=1;k<N;++k) c.a[i][j]=(c.a[i][j]+(ll)a[i][k]*b.a[k][j])%m; return c; } }ans,base; void qmul(int b){ while(b){ if(b&1) ans=base*ans; base=base*base,b>>=1; } } int main(){ // freopen("in2.txt","r",stdin); rd(n),rd(m); if(n==1) return puts("1"),0; if(n==2) return puts("3"),0; base.a[1][1]=base.a[1][2]=base.a[2][2]=base.a[2][3]=base.a[3][3]=base.a[3][4]=base.a[4][3]=1; ans.a[2][1]=ans.a[3][1]=ans.a[4][1]=1; qmul(n-1); printf("%d",(-ans.a[1][1]+(ll)n*ans.a[2][1]+m)%m); return 0; }
......不想写了
其实吧,我觉得不用死记矩阵乘法的规则,你只用弄清楚你拿来干什么,然后根据你要搞的东西来写就是了
前置(我只是截图下来好玩)
from算法导论矩阵部分
概念
正方形nXn矩阵非常常见。我们通常对方阵的几个特例感兴趣。
1.若一个矩阵中对于任意i≠j,均有a,=0,则该矩阵是一个对角矩阵。因为对角矩阵的非对角元素均为0,所以只需要列出其对角线上的元素就可以表示一个对角矩阵:
2.称对角线元素均为1的nXn对角矩阵为nXn单位矩阵In :
单位矩阵的第i列是单位向量ei.
矩阵基本操作