洛谷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;
}
posted @ 2025-12-02 20:12  quanjun  阅读(3)  评论(0)    收藏  举报