​题目传送门​

一、矩阵分析

P1962 斐波那契数列_i++

P1962 斐波那契数列_快速幂_02

以此类推

P1962 斐波那契数列_初始化_03

所以要求斐波那契的第\(n\)项,我们只需要求得\(F(2)\)和\(F(1)\)构成的矩阵与特定矩阵的\(n-2\)次方相乘后的矩阵,然后取该矩阵的第一行第一列的元素值就是\(F(n)\)

二、实现代码I

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 10;
const int MOD = 1e9 + 7;

//矩阵声明
struct JZ {
LL m[N][N];
} res, base;

inline JZ mul(JZ A, JZ B) {
JZ C;
memset(C.m, 0, sizeof(C.m));
for (int i = 1; i <= 2; i++)
for (int j = 1; j <= 2; j++)
for (int k = 1; k <= 2; k++) {
C.m[i][j] = (C.m[i][j] + (A.m[i][k] * B.m[k][j]) % MOD) % MOD;
}
return C;
}

//快速幂
inline void qmi(LL k) {
memset(res.m, 0, sizeof res.m);
res.m[1][1] = res.m[1][2] = 1; // f(1)=1,f(2)=1 乘一次矩阵就是f(3),所以f(n)就是n-2次方
while (k) {
if (k & 1) res = mul(res, base);
base = mul(base, base);
k >>= 1;
}
}
int main() {
LL n;
cin >> n;
if (n <= 2) {
puts("1");
return 0;
}
//结果矩阵初始化
memset(base.m, 0, sizeof base.m);
base.m[1][1] = base.m[1][2] = base.m[2][1] = 1;
/*
1 1
1 0
base 矩阵
*/
//快速幂
qmi(n - 2);
//结果
cout << (res.m[1][1]) % MOD << endl;
return 0;
}

三、实现代码II

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 10;
const int MOD = 1e9 + 7;

LL base[N][N], res[N][N];

inline void mul(LL C[][N], LL A[][N], LL B[][N]) {
static LL tmp[N][N];
memset(tmp, 0, sizeof(tmp));
for (int i = 1; i <= 2; i++)
for (int j = 1; j <= 2; j++)
for (int k = 1; k <= 2; k++)
tmp[i][j] = (tmp[i][j] + (A[i][k] * B[k][j]) % MOD) % MOD;
memcpy(C, tmp, sizeof tmp);
}

//快速幂
inline void qmi(LL k) {
//初始化结果数组的(i,i)=1
memset(res, 0, sizeof res);
res[1][1] = res[1][2] = 1;
while (k) {
if (k & 1) mul(res, res, base);
mul(base, base, base);
k >>= 1;
}
}

int main() {
LL n;
cin >> n;
if (n <= 2) {
puts("1");
return 0;
}
//结果矩阵初始化
memset(base, 0, sizeof base);
base[1][1] = base[1][2] = base[2][1] = 1;
//快速幂
qmi(n - 2);
//结果
cout << (res[1][1]) % MOD << endl;
return 0;
}