矩阵快速幂+矩阵幂的前n项和模板

模板:

相关题目

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;
typedef long long ll;
const ll mod = 1e9+7;;

int n;

class Matrix{
public:
    int row, col;
    ll v[54][54];
    Matrix(){}
    ~Matrix(){}
    Matrix operator + (const Matrix &sec) const;
    Matrix operator * (const Matrix &sec) const;
    Matrix & operator = (const Matrix &sec);
    Matrix pow(ll n) const;
};

Matrix Matrix::operator + (const Matrix &sec) const{
    Matrix tmp;
    tmp.row = sec.row, tmp.col = sec.col;
    for(int i = 1; i <= tmp.row; i++){
        for(int j = 1; j <= tmp.col; j++){
            tmp.v[i][j] = (v[i][j] + sec.v[i][j]) % mod;
        }
    }
    return tmp;
}
Matrix Matrix::operator * (const Matrix &sec) const{
    Matrix tmp;
    tmp.row = row, tmp.col = sec.col;
    memset(tmp.v, 0, sizeof(tmp.v));
    for(int i = 1; i <= row; i++){
        for(int j = 1; j <= sec.col; j++){
            for(int k = 1; k <= col; k++){
                tmp.v[i][j] += (v[i][k]*sec.v[k][j]);
                tmp.v[i][j] %= mod;
            }
        }
    }
    return tmp;
}
Matrix & Matrix::operator = (const Matrix &sec){
    for(int i = 1; i <= row; i++){
        for(int j = 1; j <= col; j++){
            v[i][j] = sec.v[i][j];
        }
    }
    return *this;
}
Matrix Matrix::pow(ll n) const{
    Matrix a(*this);
    Matrix ans;
    ans.row = row, ans.col = col;
    memset(ans.v, 0, sizeof(ans.v));
    for(int i = 1; i <= ans.row; i++)
        ans.v[i][i] = 1;
    while(n){
        if(n & 1LL)
            ans = ans * a;
        a = a * a;
        n >>= 1LL;
    }
    return ans;
}

Matrix pow_sum(const Matrix &a, ll n);/*倍增法求解A^1 + A^2 + ... + A^n*/

/*倍增法求解A^1 + A^2 + ... + A^n*/
Matrix pow_sum(const Matrix &a, ll n){
    ///递归终点
    if(n == 1LL) return a;
    ///tmp递归表示A^1 + A^2 + ... + A^(n/2)
    Matrix tmp = pow_sum(a, n/2);
    ///sum表示(A^1+...+A^(n/2)) + (A^1+...+A^(n/2))*(A^(n/2))
    Matrix sum = tmp + tmp*a.pow(n/2);
    ///若n为奇数,n/2 + n/2 = n-1, 因此sum需要加上A^(n)这一项
    if(n & 1LL) sum = sum + a.pow(n);
    return sum;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值