矩阵
矩阵的定义:

一个n*m的矩阵可以看作是一个二维数组

设A是\(n * m\)矩阵,B是 \(m * p\)矩阵

则C就是\(n * p\) 矩阵 并且


\[\sum _{k=1}^{m} A_{i,k}*B_{k,j}\]


矩阵乘法满足结合律,即\((A*B)*C\) =\(A*(B*C)\)

满足分配律,即\((A+B)*C\)=\(A*C+B*C\)



矩阵的递推应用

若F1 是 \(1*n\)矩阵,F2是\(n*n\)矩阵,F3=F1*F2

F1,F3可看作一维数组

这时我们发现,矩阵乘法就可以用来做一些递推式

举个矩阵乘法_#include

假如一个递推式是 \(f[i]=f[i-1]+f[i-2]\)(斐波那契数列)

那么它的我们就可以设它的A矩阵为

A={\(f[i-1]\) \(f[i]\)}

想要得到的C矩阵就应该是

C={\(f[i]\) \(f[i+1]\)}

此时,我们是不是只要找到一个\(n*n\)的B矩阵就可以使得\(A*B=C\)

那么怎么构造B矩阵呢?首先我们要理解一下C数组

\(C[i][j]\)表示的应该就是A数组第i行的每个数分别乘上B数组第j行的每个数

那么对于这个题来说

我们要得到的\(C[1][1]\)是不是\(f[i]\)

那么我们只要\(f[i-1]\)乘上0,f[i]乘上1是不是就行了

所以说B的第一列是0,1

另外

我们观察\(f[i+1]\) 显然\(f[i+1]=f[i]+f[i-1]\),

所以我们要让\(f[i-1]*1+f[i]*1\)

所以B数组就是

0 1

1 1

同时我们发现,F3=F1*F2

F4=F3*F2

\(F5=F4*F2=F3*F2*F2=F1*F2^3\)

即\(Fn=F1*F2^{n-1}\)

最后贴一份斐波那契的代码罢

#include <iostream>
#include <cstring>
using namespace std;
#define Max_rank 3
#define mod 1000000007

struct Matrix {
long long a[Max_rank][Max_rank];
Matrix(){memset(a, 0, sizeof(a));}
void init(){
a[1][1] = a[1][2] = a[2][1] = 1;
a[2][2] = 0;
}
Matrix operator*(const Matrix b) {
Matrix 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] + a[i][k]*b.a[k][j])%mod;
return res;
}
};

long long qpow(long long n){
Matrix ans,base;
ans.init();
base.init();
while(n>0){
if(n&1) ans=ans*base%mod;
base=base*base%mod;
n>>=1;
}
return ans.a[1][1]%mod;
}
int main() {
long long n;
scanf("%lld",&n);
cout << qpow(n-2) << endl;
return 0;
}