洛谷U637812 三波那契数列 题解 矩阵快速幂
题目链接:https://www.luogu.com.cn/problem/U637812
题目大意
- \(a_1 = 0\)
- \(a_2 = 0\)
- \(a_3 = 1\)
- 当 \(i \gt 3\) 时,\(a_i = a_{i-3} + a_{i-2} + a_{i-1}\)
求 \(a_n\),答案对 \(10^9 + 7\) 取模。
\(1 \le n \le 10^{12}\)。
解题思路
因为
\[\begin{bmatrix} a_{i-2} & a_{i-1} & a_{i} \end{bmatrix} \times \begin{bmatrix} 0 & 0 & 1 \\ 1 & 0 & 1 \\ 0 & 1 & 1 \end{bmatrix} = \begin{bmatrix} a_{i-1} & a_i & a_{i+1} \end{bmatrix}
\]
所以
\[\begin{bmatrix} a_{1} & a_{2} & a_{3} \end{bmatrix} \times \begin{bmatrix} 0 & 0 & 1 \\ 1 & 0 & 1 \\ 0 & 1 & 1 \end{bmatrix} ^ {n-3} = \begin{bmatrix} a_{n-2} & a_{n-1} & a_{n} \end{bmatrix}
\]
示例程序:
#include <bits/stdc++.h>
using namespace std;
const long long mod = 1e9 + 7;
struct Matrix {
int n, m;
long long a[3][3];
void init(int _n, int _m) {
n = _n;
m = _m;
memset(a, 0, sizeof a);
}
Matrix operator * (const Matrix &b) const {
Matrix res;
res.init(n, b.m);
assert(m == b.n);
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
for (int k = 0; k < b.m ; k++)
res.a[i][k] = (res.a[i][k] + a[i][j] * b.a[j][k] % mod) % mod;
return res;
}
Matrix operator ^ (long long b) {
Matrix res, t;
res.init(n, n);
for (int i = 0; i < n; i++) res.a[i][i] = 1;
t = *this;
for (; b; b >>= 1, t = t * t)
if (b & 1ll)
res = res * t;
return res;
}
};
long long n;
int main() {
cin >> n;
if (n <= 2) cout << 0 << endl;
else if (n == 3) cout << 1 << endl;
else {
Matrix A, B;
A.init(1, 3);
A.a[0][2] = 1;
B.init(3, 3);
B.a[1][0] = 1;
B.a[2][1] = 1;
B.a[0][2] = 1;
B.a[1][2] = 1;
B.a[2][2] = 1;
B = B ^ (n-3);
A = A * B;
cout << A.a[0][2] << endl;
}
return 0;
}
浙公网安备 33010602011771号