码迷,mamicode.com
首页 > 其他好文 > 详细

矩阵快速幂

时间:2016-03-10 00:06:29      阅读:176      评论:0      收藏:0      [点我收藏+]

标签:

在遇到一些递推式时,如果我们直接按公式一步步进行运算,效率较低。构造矩阵进行快速运算,可以高效地解决这个问题。

以int型方阵为例:

 

矩阵结构:

struct Mat{
    int mat[n][n];
};

 

矩阵乘法:

Mat mul(Mat a,Mat b)
{
    Mat ret;
    memset(ret,0,sizeof(ret));
    for(int i = 0; i<n; ++i)
        for(int j = 0; j<n; ++j)
            for(int k = 0; k<n; ++k)
                ret.mat[i][j] += a[i][k]*b[k][j];
    return ret;
}

 

快速计算方阵a的k次幂:

Mat matquickpow(Mat a,int k)
{
    Mat ret;
    for(int i = 0; i<n; ++i)
        for(int j = 0; j<n; ++j)
            ret.mat[i][j] = (i == j);   //初始化为单位矩阵
    while(k){
        if(k&1)
            ret = mul(a,a);
        a = mul(a,a);
        k >>= 1;
    }
    return ret;
}

 

快速计算方阵a的k次幂对mod取模的一步运算:

Mat mulmod(Mat a,Mat b,int mod)
{
    Mat ret;
    memset(ret,0,sizeof(ret));
    for(int i = 0; i<n; ++i)
        for(int j = 0; j<n; ++j)
            for(int k = 0; k<n; ++k)
                ret.mat[i][j] = (ret.mat[i][j]+a[i][k]*b[k][j])%mod;
                //对于某些题目,当结果为负数不合题意时,可以对最终结果进行处理
                //或者将此处改为ret.mat[i][j] = ((ret.mat[i][j]+a[i][k]*b[k][j])%mod+mod)%mod;
    return ret;
}

 

快速计算方阵a的k次幂对mod取模:

Mat matquickpowmod(Mat a,int k,int m)
{
    Mat ret;
    for(int i = 0; i<n; ++i)
        for(int j = 0; j<n; ++j)
            ret.mat[i][j] = (i == j);   //初始化为单位矩阵
    while(k){
        if(k&1)
            ret = mulmod(a,a);
        a = mulmod(a,a);
        k >>= 1;
    }
    return ret;
}

 

例如,对于斐波那契数列的递推部分,我们可以运用矩阵快速幂进行计算:

将Fn+2 = Fn+Fn+1转换为

技术分享

就可以运用矩阵快速幂进行计算了。

 

矩阵快速幂

标签:

原文地址:http://www.cnblogs.com/inmoonlight/p/5259912.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!