poj3070 Fibonacci(矩阵快速幂取模)

题目链接: poj2070 Fibonacci

\(Fibonacci\) 数列有: \(F_0=0, F_1=1, F_n=F_{n-1}+F_{n-2}(n\ge 2)\) .

于是

\[\begin{align} \begin{pmatrix} F_{n+1} & F_n \\ F_n & F_{n-1}\end{pmatrix} &=\begin{pmatrix} 1 & 1 \\ 1 & 0\end{pmatrix} \begin{pmatrix} F_{n} & F_{n-1} \\ F_{n-1} & F_{n-2}\end{pmatrix} \\ &=\cdots \\ &=\begin{pmatrix} 1 & 1 \\ 1 & 0\end{pmatrix}^{n-1} \begin{pmatrix} F_2 & F_1 \\ F_1 & F_0\end{pmatrix} \\ &=\begin{pmatrix} 1 & 1 \\ 1 & 0\end{pmatrix}^n \end{align} \]

事实上题目已经给出了公式,直接套用就好了。
定义一个矩阵结构体并重载 \(*\) ,矩阵快速幂的写法就与普通快速幂几乎一样了。

/**
 * poj3070 Fibonacci
 * 矩阵快速幂取模
 */

#include <iostream>
#include <climits>
#include <vector>
using namespace std;

typedef long long LL;

struct Matrix
{
    LL mod;
    vector<vector<LL> > m;
    Matrix(int row, int col, LL mod = LLONG_MAX)
    {
        this->mod = mod;
        m.resize(row, vector<LL>(col));
    }
    Matrix operator * (const Matrix &t) const
    {
        int row = m.size(), col = t.m[0].size(), cnt = m[0].size();
        Matrix res(row, col, mod);
        for (int i = 0; i < row; ++i) {
            for (int j = 0; j < col; ++j) {
                for (int k = 0; k < cnt; ++k) {
                    res.m[i][j] += m[i][k]*t.m[k][j]%mod;
                    res.m[i][j] %= mod;
                }
            }
        }
        return res;
    }
};

Matrix fastPow(Matrix a, LL b, LL mod = LLONG_MAX)
{
    int n = a.m.size();
    Matrix t(n, n, mod);
    for (int i = 0; i < n; ++i) t.m[i][i] = 1;
    while (b) {
        if (b&1) t = t*a;
        a = a*a;
        b >>= 1;
    }
    return t;
}

const int mod = 10000;

int main()
{
    int n;
    Matrix A(2, 2, mod);
    A.m[0][0] = A.m[0][1] = A.m[1][0] = 1;
    while (cin >> n && ~n) {
        cout << fastPow(A, n, mod).m[0][1] << endl;
    }
    return 0;
}

模板总结

在此总结一个存储矩阵的模板,以后遇到题目再完善

struct Matrix
{
    LL mod;
    vector<vector<LL> > m;
    Matrix(int row, int col, LL mod = LLONG_MAX)
    {
        this->mod = mod;
        m.resize(row, vector<LL>(col));
    }
    Matrix operator * (const Matrix &t) const
    {
        int row = m.size(), col = t.m[0].size(), cnt = m[0].size();
        Matrix res(row, col, mod);
        for (int i = 0; i < row; ++i) {
            for (int j = 0; j < col; ++j) {
                for (int k = 0; k < cnt; ++k) {
                    res.m[i][j] += m[i][k]*t.m[k][j]%mod;
                    res.m[i][j] %= mod;
                }
            }
        }
        return res;
    }
};
posted @ 2021-01-31 20:00  Zewbie  阅读(85)  评论(0编辑  收藏  举报