zoukankan      html  css  js  c++  java
  • 洛谷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) 洛谷的测评机今天估计出问题了。

  • 相关阅读:
    Object-C,NSSet,不可变集合
    NYIST 860 又见01背包
    NYIST 1070 诡异的电梯【Ⅰ】
    HDU 1542 Atlantis
    HDU 4756 Install Air Conditioning
    CodeForces 362E Petya and Pipes
    HDU 4751 Divide Groups
    HDU 3081 Marriage Match II
    UVA 11404 Palindromic Subsequence
    UVALIVE 4256 Salesmen
  • 原文地址:https://www.cnblogs.com/quanjun/p/13940127.html
Copyright © 2011-2022 走看看