矩阵乘法

148 阅读2分钟

斐波那契

要计算斐波那契数列的前 ( n ) 项和,我们可以使用矩阵快速幂来解决。首先,让我们回顾一下斐波那契数列的递推关系:

F(n)=F(n1)+F(n2)F(n) = F(n-1) + F(n-2)

我们可以将这个递推关系表示为以下形式的矩阵乘法:

(F(n)F(n1))=(1110)×(F(n1)F(n2))\begin{pmatrix} F(n) \\ F(n-1) \end{pmatrix} = \begin{pmatrix} 1 & 1 \\ 1 & 0 \end{pmatrix} \times \begin{pmatrix} F(n-1) \\ F(n-2) \end{pmatrix}

因此,我们可以将斐波那契数列的前 ( n ) 项和表示为以下形式的矩阵乘法:

(F(n+1)F(n))=(1110)n×(F(2)F(1))\begin{pmatrix} F(n+1) & F(n) \end{pmatrix} = \begin{pmatrix} 1 & 1 \\ 1 & 0 \end{pmatrix}^n \times \begin{pmatrix} F(2) & F(1) \end{pmatrix}

这里,矩阵的乘法使用了矩阵快速幂算法。最后,( F(n+1) ) 就是斐波那契数列的前 ( n ) 项和。

下面是用 C++ 实现的计算斐波那契数列前 ( n ) 项和的代码:

#include <iostream>
#include <vector>

using namespace std;

const int MOD = 1000000007; // 取模的值

// 定义矩阵结构体
struct Matrix {
    long long a, b, c, d;
};

// 矩阵乘法
Matrix multiply(Matrix m1, Matrix m2) {
    Matrix res;
    res.a = (m1.a * m2.a + m1.b * m2.c) % MOD;
    res.b = (m1.a * m2.b + m1.b * m2.d) % MOD;
    res.c = (m1.c * m2.a + m1.d * m2.c) % MOD;
    res.d = (m1.c * m2.b + m1.d * m2.d) % MOD;
    return res;
}

// 快速幂算法计算矩阵的 n 次幂
Matrix power(Matrix m, long long n) {
    Matrix res = {1, 0, 0, 1}; // 单位矩阵
    while (n > 0) {
        if (n & 1) {
            res = multiply(res, m);
        }
        m = multiply(m, m);
        n >>= 1;
    }
    return res;
}

// 计算斐波那契数列前 n 项和
long long fibonacciSum(long long n) {
    // 构建矩阵 M
    Matrix M = {1, 1, 1, 0};

    // 计算 M 的 n 次幂
    Matrix Mn = power(M, n);

    // 初始值 F(1) 和 F(2)
    long long F1 = 1;
    long long F2 = 1;

    // 计算 F(n+1)
    long long Fn_1 = (Mn.a * F2 + Mn.b * F1) % MOD;

    // 返回斐波那契数列前 n 项和
    return (Fn_1 - 1 + MOD) % MOD; // 减去 F(1) 的值并取模
}

int main() {
    long long n;
    cout << "Enter the value of n: ";
    cin >> n;

    // 计算斐波那契数列前 n 项和
    long long result = fibonacciSum(n);

    cout << "Result: " << result << endl;

    return 0;
}

这段代码中,我们使用了矩阵快速幂算法来计算矩阵 ( M ) 的 ( n ) 次幂,然后根据 ( M ) 的结果计算斐波那契数列的前 ( n ) 项和。

xn+(1x)nx^n + \left(\frac{1}{x}\right)^n 是多少

3.方程【算法赛】 - 蓝桥云课 (lanqiao.cn)

首先,根据题目已知的条件 x+1x=kx + \frac{1}{x} = k,我们可以将其整理为 x2kx+1=0x^2 - kx + 1 = 0 的二次方程,并解出 xx 的表达式:

x=k±k242x = \frac{k \pm \sqrt{k^2 - 4}}{2}

现在,我们需要计算 xn+(1x)nx^n + \left(\frac{1}{x}\right)^n。可以通过以下递推关系来计算:

xn+(1x)n=(xn1+(1x)n1)(x+1x)(xn2+(1x)n2)x^n + \left(\frac{1}{x}\right)^n = (x^{n-1} + \left(\frac{1}{x}\right)^{n-1}) \cdot (x + \frac{1}{x}) - (x^{n-2} + \left(\frac{1}{x}\right)^{n-2})

我们可以使用这个递推关系来计算 xn+(1x)nx^n + \left(\frac{1}{x}\right)^n 的值,同时在每一步计算中都进行取模操作。 好的,根据给出的递推关系,我们可以将其表示为矩阵的形式。

首先,我们定义一个矩阵 MM 如下:

M=(F(1)110)M = \begin{pmatrix} F(1) & 1 \\ -1 & 0 \end{pmatrix}

然后,我们用快速幂算法计算矩阵 MM 的 n-2 次幂,得到矩阵 Mn2M^{n-2}

接着,我们定义初始矩阵 VV 如下:

V=(F(2)F(1))=(k22k)V = \begin{pmatrix} F(2) & F(1) \end{pmatrix} = \begin{pmatrix} k^2-2 & k \end{pmatrix}

最后,我们计算矩阵 VV 与矩阵 Mn2M^{n-2} 的乘积,即 V×Mn2V \times M^{n-2},得到的结果即为 F(n)F(n)


const int MOD = 1000000007; // 取模的值

// 定义矩阵结构体
struct Matrix {
    long long a, b, c, d;
};

// 矩阵乘法
Matrix multiply(Matrix m1, Matrix m2) {
    Matrix res;
    res.a = (m1.a * m2.a + m1.b * m2.c) % MOD;
    res.b = (m1.a * m2.b + m1.b * m2.d) % MOD;
    res.c = (m1.c * m2.a + m1.d * m2.c) % MOD;
    res.d = (m1.c * m2.b + m1.d * m2.d) % MOD;
    return res;
}

// 快速幂算法计算矩阵的 n 次幂
Matrix power(Matrix m, long long n) {
    Matrix res = {1, 0, 0, 1}; // 单位矩阵
    while (n > 0) {
        if (n & 1) {
            res = multiply(res, m);
        }
        m = multiply(m, m);
        // debug4(m.a,m.b,m.c,m.d);
        n >>= 1;
    }
    return res;
}

// 计算 F(n)
long long calculate(long long k, long long n) {
    Matrix M = {k, 1, -1, 0};
    Matrix Mn_2 = power(M, n - 2);
    
    long long F1 = k % MOD;
    long long F2 = (k * k - 2) % MOD;
    
    long long Fn = (Mn_2.a * F2 % MOD + Mn_2.c * F1 % MOD + 2*MOD) % MOD;

    return Fn;
}