火龙信奥
  • 首页
  • 课程
  • 题库
  • 打卡
    • 代码对战
    • 快速对战
  • 题单
  • 团队
  • 荣誉墙
  • 商城
  • 登录 / 注册

矩阵快速幂详解与应用

作者: 作者的头像   huolong , 时间:2025-11-24 20:44:43 , 所有人可见, 阅读  28

矩阵快速幂详解与应用

矩阵快速幂是一种用于高效计算线性递推关系的方法,时间复杂度为O(log n),特别适合处理大型递推问题。本文将详细讲解如何推导递推矩阵,并以斐波那契数列和Pell数列为例,展示C++11实现代码。

一、矩阵快速幂基本原理

1.1 核心思想

  1. 将递推关系转换为矩阵乘法形式
  2. 使用快速幂算法计算矩阵的n次幂
  3. 通过矩阵乘法得到最终结果

1.2 通用步骤

  1. 确定递推关系式
  2. 构造递推矩阵
  3. 确定初始状态向量
  4. 计算矩阵的幂
  5. 通过矩阵乘法得到结果

二、斐波那契数列

2.1 递推关系

斐波那契数列定义为:

F(n) = F(n-1) + F(n-2)
F(0) = 0, F(1) = 1

2.2 递推矩阵推导

将递推关系转换为矩阵形式:

| F(n)   |   =  | 1  1 | * | F(n-1) |
| F(n-1) |     | 1  0 |   | F(n-2) |

进一步展开:

| F(n)   |   =  | 1  1 |^(n-1) * | F(1) |
| F(n-1) |     | 1  0 |          | F(0) |

因此,递推矩阵为:

M = 
| 1  1 |
| 1  0 |

三、Pell数列

3.1 递推关系

Pell数列定义为:

P(n) = 2*P(n-1) + P(n-2)
P(0) = 0, P(1) = 1

3.2 递推矩阵推导

将递推关系转换为矩阵形式:

| P(n)   |   =  | 2  1 | * | P(n-1) |
| P(n-1) |     | 1  0 |   | P(n-2) |

进一步展开:

| P(n)   |   =  | 2  1 |^(n-1) * | P(1) |
| P(n-1) |     | 1  0 |          | P(0) |

因此,递推矩阵为:

M = 
| 2  1 |
| 1  0 |

四、C++11实现代码

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

typedef vector<vector<long long>> Matrix;
const long long MOD = 1000000007; // 取模防止溢出

// 矩阵乘法
Matrix multiply(const Matrix& A, const Matrix& B) {
    int n = A.size();
    int p = B.size();
    int m = B[0].size();

    Matrix C(n, vector<long long>(m, 0));
    for (int i = 0; i < n; i++) {
        for (int k = 0; k < p; k++) {
            if (A[i][k] == 0) continue; // 优化:跳过0元素
            for (int j = 0; j < m; j++) {
                C[i][j] = (C[i][j] + A[i][k] * B[k][j]) % MOD;
            }
        }
    }
    return C;
}

// 矩阵快速幂
Matrix matrix_pow(Matrix base, long long exp) {
    int n = base.size();
    Matrix result(n, vector<long long>(n, 0));

    // 初始化为单位矩阵
    for (int i = 0; i < n; i++) {
        result[i][i] = 1;
    }

    while (exp > 0) {
        if (exp & 1) {
            result = multiply(result, base);
        }
        base = multiply(base, base);
        exp >>= 1;
    }

    return result;
}

// 斐波那契数列 (F(0)=0, F(1)=1)
long long fibonacci(long long n) {
    if (n == 0) return 0;
    if (n == 1) return 1;

    // 递推矩阵
    Matrix base = {{1, 1}, 
                   {1, 0}};

    // 计算 base^(n-1)
    Matrix result = matrix_pow(base, n-1);

    // F(n) = result[0][0]*F(1) + result[0][1]*F(0)
    return result[0][0];
}

// Pell数列 (P(0)=0, P(1)=1)
long long pell(long long n) {
    if (n == 0) return 0;
    if (n == 1) return 1;

    // 递推矩阵
    Matrix base = {{2, 1}, 
                   {1, 0}};

    // 计算 base^(n-1)
    Matrix result = matrix_pow(base, n-1);

    // P(n) = result[0][0]*P(1) + result[0][1]*P(0)
    return result[0][0];
}

int main() {
    cout << "=== Fibonacci Sequence ===" << endl;
    for (int i = 0; i <= 10; i++) {
        cout << "F(" << i << ") = " << fibonacci(i) << endl;
    }

    cout << "\n=== Pell Sequence ===" << endl;
    for (int i = 0; i <= 10; i++) {
        cout << "P(" << i << ") = " << pell(i) << endl;
    }

    // 测试大数值
    long long n = 1000000000;
    cout << "\nLarge values (mod " << MOD << "):" << endl;
    cout << "F(" << n << ") = " << fibonacci(n) << endl;
    cout << "P(" << n << ") = " << pell(n) << endl;

    return 0;
}

五、代码说明

5.1 关键函数

multiply: 实现矩阵乘法,支持取模运算 matrix_pow: 实现矩阵快速幂算法 fibonacci: 计算斐波那契数列的第n项 pell: 计算Pell数列的第n项

5.2 优化技巧

跳过0元素: 在矩阵乘法中,如果元素为0,跳过内层循环 取模运算: 防止整数溢出,通常取10^9+7 位运算: 使用位运算(&, >>=)替代模2和除2操作,提高效率

5.3 时间复杂度

矩阵乘法: $O(n^3)$,其中n为矩阵维度(本例中为2) 矩阵快速幂: $O(log k)$,其中k为幂次 总体复杂度: $O(n^3 log k)$,对于2x2矩阵,可视为 $O(log k)$

—— 本文来自火龙信奥(义乌睿码科技):义乌青少年信息学奥赛与编程教育平台,专注 CSP-J/S、NOIP、GESP 竞赛培训,线上线下融合教学,助力编程升学。网址:hlcoding.com

©2026加盟我们 | 关于我们 | ACM课程 | 常见问题 | 成果墙 | 评测记录 | 浙ICP备2021013995号
在线画图 | OI WIki | 打字练习
火龙信奥
请输入登录信息


请完成安全验证
验证码底图 滑块
向右拖动滑块完成验证
请输入用户名 / 绑定的手机号码



请输入注册信息(手机号验证码注册)





验证码5分钟有效,60秒内不可重复获取,每日最多3次

微信登录

微信登录二维码

正在生成二维码...

账号已过期,请续期。
去续期

绑定手机号

📱

为了更好地保护您的账号安全,享受完整的平台服务

请您尽快绑定手机号码