$a_1=a_2=a_3=1$
$a_n=a_{n-3}+a_{n-1}\quad(n>3)$
有$T$组询问。对每组询问,给定$n$,求$a_n\mod 1000000007$。
$T\leq 100,n\leq 2\times 10^9$。
首先假定你会矩阵快速幂(不会的看:这里)
那么,我们可以构造列向量
$$C_{n}=\begin{bmatrix}a_{n-2}\\a_{n-1}\\a_{n}\end{bmatrix}$$
,然后想办法构造一个$3x3$的矩阵$A$,使得
$$A\times C_{n}=C_{n+1}$$
显然,$A$可以等于
$$\begin{bmatrix}0&1&0\\0&0&1\\1&0&1\end{bmatrix}$$
然后矩阵快速幂一波就可以在$\mathcal O(\lg n)$的时间内求出$a_{n}$了。
贴代码:
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef array<array<ll, 4>, 4> Matrix; const ll P = 1000000007; ll n, k; Matrix A, I; Matrix MatrixMul(const Matrix &A, const Matrix &B) { Matrix ret; for (int i=1; i<=n; i++) for (int j=1; j<=n; j++) { ret[i][j] = 0; for (int k=1; k<=n; k++) (ret[i][j] += A[i][k] * B[k][j] % P) %= P; } return ret; } Matrix PowerMod(ll k) { if (k == 0) return I; if (k == 1) return A; if (k & 1) return MatrixMul(PowerMod(k-1), A); Matrix B = PowerMod(k >> 1); return MatrixMul(B, B); } signed main() { int T; scanf("%d", &T); n = 3; I[1][1] = I[2][2] = I[3][3] = 1; A[1][2] = A[2][3] = A[3][1] = A[3][3] = 1; while (T--) { int n; scanf("%d", &n); if (n <= 3) puts("1"); else { Matrix ret = PowerMod(n - 3); printf("%lld\n", (ret[3][1] + ret[3][2] + ret[3][3]) % P); } } return 0; }
原文:https://www.cnblogs.com/mchmch/p/luogu-p1939.html