矩阵快速幂

矩阵快速幂是一种利用快速幂思想计算矩阵幂次的高效算法。主要用于解决线性递推问题,能够将 O(n) 的线性计算优化到 O(k³ log n),其中 k 是矩阵维度。

 

1. 核心思想

将普通快速幂的思想扩展到矩阵运算:

  • 计算矩阵的 n 次幂:Aⁿ

  • 利用二进制分解:n = 2ᵃ + 2ᵇ + ...

  • 例如:A¹³ = A⁸ × A⁴ × A¹

 

例题:波斐契那数列_牛客题霸_牛客网

#include<bits/stdc++.h>
using namespace std;
#define ll long long
typedef pair<int, int> pii;
typedef pair<long, long> pll;
const int mod = 1e9 + 7;

//普通快速幂
int binpow(int a, int b){
    if(b == 0) return 1;
    int res = 1;
    while(b){
        if(b & 1) res = res * a;
        a = a * a;
        b >>= 1;
    }
    return res;
}

struct Matrix{
    int a[3][3] = {0};

    //初始化单位矩阵
    static Matrix init(){
        Matrix T;
        for(int i = 0; i < 3; ++i) T.a[i][i] = 1;
        return T;
    }

    //运算符重载(用于计算矩阵间的乘法)
    Matrix operator*(Matrix &other){
        Matrix res;
        //res[i][j] = 第i行元素*第j列元素
        for(int i = 0; i < 3; ++i){
            for(int j = 0; j < 3; ++j){
                res.a[i][j] = (a[i][0] * other.a[0][j] + 
                            a[i][1] * other.a[1][j] + 
                            a[i][2] * other.a[2][j]) % mod;
            }
        }
        return res;
    }
    
};

//矩阵快速幂(重载)
Matrix binpow(Matrix a, int b){
    Matrix res = Matrix::init();
    while(b){
        if(b & 1) res = res * a;
        a = a * a;
        b >>= 1;
    }
    return res;
}


void solve(){
    int n;
    cin >> n;

    if(n <= 3){
        cout << 1 << '\n';
        return ;
    }
    Matrix T;
    T.a[0][0] = 0, T.a[0][1] = 1, T.a[0][2] = 0;
    T.a[1][0] = 0, T.a[1][1] = 0, T.a[1][2] = 1;
    T.a[2][0] = 1, T.a[2][1] = 0, T.a[2][2] = 1;
             
    Matrix ans = binpow(T, n - 3);
    cout << (ans.a[2][0] + ans.a[2][1] + ans.a[2][2]) % mod << '\n';
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int T;
    cin >> T;
    while(T--){
        solve();
    }
    return 0;
}

 

posted @ 2026-02-27 00:40  菜鸡の编程日常  阅读(13)  评论(0)    收藏  举报