• 洛谷P1962 斐波那契数列 题解 矩阵快速幂


    题目链接:https://www.luogu.com.cn/problem/P1962

    解题思路:

    矩阵快速幂模板题。

    但是我用 递归写,交的时候总是莫名 RE 两组,而且 RE 的两组还是不固定的,有的时候这两组 RE,有的时候那两组 RE。

    递归代码如下(可能会 RE):

    #include <bits/stdc++.h>
    using namespace std;
    const long long MOD = 1000000007;
    long long n;
    struct Matrix {
        int n, m;
        long long a[2][2];
        Matrix() {};
        Matrix(int _n, int _m) { n = _n; m = _m; }
        Matrix operator * (Matrix b) {
            Matrix c = Matrix(n, b.m);
            memset(c.a, 0, sizeof(c.a));
            for (int i = 0; i < n; i ++)
                for (int j = 0; j < b.m; j ++)
                    for (int k = 0; k < m; k ++)
                        c.a[i][j] += a[i][k] * b.a[k][j] % MOD, c.a[i][j] %= MOD;
            return c;
        }
        void test() {
            cout << "n = " << n << ", m = " << m << endl;
            for (int i = 0; i < n; i ++) {
                for (int j = 0; j < m; j ++) cout << a[i][j] << " ";
                cout << endl;
            }
        }
    };
    Matrix solve(Matrix a, long long n) {
        if (n == 1) return a;
        Matrix b = solve(a, n/2);
        b = b * b;
        if (n % 2) b = b * a;
        return b;
    }
    int main() {
        cin >> n;
        if (n <= 2) cout << 1 << endl;
        else {
            Matrix a = Matrix(2, 2);
            a.a[0][0] = 0; a.a[0][1] = a.a[1][0] = a.a[1][1] = 1;
            Matrix b = Matrix(2, 1);
            b.a[0][0] = b.a[1][0] = 1;
            cout << (solve(a, n-1) * b).a[0][0] << endl;
        }
        return 0;
    }
    

    所以改成了非递归的写法,如下:

    #include <bits/stdc++.h>
    using namespace std;
    const long long MOD = 1000000007;
    long long n;
    struct Matrix {
        int n, m;
        long long a[2][2];
        Matrix() {};
        Matrix(int _n, int _m) { n = _n; m = _m; }
        Matrix operator * (Matrix b) {
            Matrix c = Matrix(n, b.m);
            memset(c.a, 0, sizeof(c.a));
            for (int i = 0; i < n; i ++)
                for (int j = 0; j < b.m; j ++)
                    for (int k = 0; k < m; k ++)
                        c.a[i][j] += a[i][k] * b.a[k][j] % MOD, c.a[i][j] %= MOD;
            return c;
        }
        void test() {
            cout << "n = " << n << ", m = " << m << endl;
            for (int i = 0; i < n; i ++) {
                for (int j = 0; j < m; j ++) cout << a[i][j] << " ";
                cout << endl;
            }
        }
    };
    Matrix solve(Matrix a, long long n) {
        Matrix c = Matrix(2, 2);
        memset(c.a, 0, sizeof(c.a));
        c.a[0][0] = c.a[1][1] = 1;
        while (n > 0) {
            if (n % 2) c = c * a;
            a = a * a;
            n /= 2;
        }
        return c;
    }
    int main() {
        cin >> n;
        if (n <= 2) cout << 1 << endl;
        else {
            Matrix a = Matrix(2, 2);
            a.a[0][0] = 0; a.a[0][1] = a.a[1][0] = a.a[1][1] = 1;
            Matrix b = Matrix(2, 1);
            b.a[0][0] = b.a[1][0] = 1;
            cout << (solve(a, n-1) * b).a[0][0] << endl;
        }
        return 0;
    }
    

    结果还是 RE。不知道怎么回事了囧、、(感觉是今天洛谷的测聘机出问题了(2020年11月7日 CSP-S复赛当天))

    反复提交了多次,终于AC了。事实证明 (Rightarrow) 洛谷的测评机今天估计出问题了。

  • 相关阅读:
    【OPENGL】第二篇 HELLO OPENGL(续)
    【转载】关于在vs2013中配置opengl红宝书第八版环境
    【OpenGL】 第一篇 OpenGL概览
    【OpenGL】第二篇 Hello OpenGL
    【OpenGL】VAO与VBO
    面试题五 数组中出现次数超过一半的数字 时间为O(n)
    intellij idea激活,免费激活方式分享
    使用接口还是使用抽象类
    CRM(Customer Relationship Management)
    java提高篇-----字符串
  • 原文地址:https://www.cnblogs.com/quanjun/p/13940127.html
Copyright © 2020-2023  润新知