矩阵快速幂学习笔记

矩阵快速幂基于快速幂原理,也就是二进制倍增的原理。可以用来求递增式的解。
首先我们来说一个简单的递增式: f(n)=f(n1)+f(n2),f(0)=1,f(1)=1 f ( n ) = f ( n − 1 ) + f ( n − 2 ) , f ( 0 ) = 1 , f ( 1 ) = 1
1.第一步要做的是构造矩阵: [f(n)f(n1)]=[1110]×[f(n)f(n1)]=[1110]2×[f(n)f(n1)]=...=[1110]n1×[f(1)f(0)] [ f ( n ) f ( n − 1 ) ] = [ 1 1 1 0 ] × [ f ( n ) f ( n − 1 ) ] = [ 1 1 1 0 ] 2 × [ f ( n ) f ( n − 1 ) ] = . . . = [ 1 1 1 0 ] n − 1 × [ f ( 1 ) f ( 0 ) ]
2.从上面矩阵我们可以看出,只要求出知道前两项,就可以通过矩阵运算求出第n项。如果不用快速幂,直接计算矩阵的话,那每次矩阵运算复杂度为8,也就是复杂度为 O((n2)8+4)=O(n) O ( ( n − 2 ) ∗ 8 + 4 ) = O ( n ) 。如果使用矩阵快速幂,那么复杂度就是 O(log2(n1)+4)=O(log2n) O ( l o g 2 ( n − 1 ) + 4 ) = O ( l o g 2 n )

#include <bits/stdc++.h>
using namespace std;
struct Mat {
    int c[2][2];
    Mat() {
        memset(c, 0, sizeof(c));
    }
    Mat operator * (const Mat& o) {
        Mat ans;
        for(int i = 0; i < 2; ++ i) {
            for(int j = 0; j < 2; ++ j) {
                for(int k = 0; k < 2; ++ k) {
                    ans.c[i][j] += c[i][k] * o.c[k][j];
                }
            }
        }
        return ans;
    }
};
Mat qpow(Mat ret, int n) {
    Mat ans;
    for(int i = 0; i < 2; ++ i) {
        ans.c[i][i] = 1;
    }
    while(n) {
        if(n & 1) {
            ans = ans * ret;
        }
        n >>= 1;
        ret = ret * ret;
    }
    return ans;
}
int main() {
    Mat ret;
    ret.c[0][0] = 1;
    ret.c[0][1] = 1;
    ret.c[1][0] = 1;
    int n;
    while(cin >> n) {
        if(n == 0) cout << 1 <<endl;
        else if(n == 1) cout << 1 << endl;
        else {
            Mat pow_ret = qpow(ret, n - 1);
            int f[2] = {1, 1}; //f[0]和f[1]
            int ans = 0;
            for(int i = 0; i < 2; ++ i) {
                ans += f[i] * pow_ret.c[0][2 - i - 1];
            }
            cout << ans << endl;
        }
    }

}

再者,如果有常数,诸如 f(n)=f(n1)+f(n2)+C f ( n ) = f ( n − 1 ) + f ( n − 2 ) + C ,可通过化简转化为标准形式,上式与 f(n1)=f(n2)+f(n3)+C f ( n − 1 ) = f ( n − 2 ) + f ( n − 3 ) + C 做差,即可得到 f(n)=2f(n1)f(n3) f ( n ) = 2 f ( n − 1 ) − f ( n − 3 )
再者,如果带有幂函数,诸如 f(n)=f(n1)+f(n2)+xn f ( n ) = f ( n − 1 ) + f ( n − 2 ) + x n ,可通过特征方程转化为标准形式

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值