zoukankan      html  css  js  c++  java
  • 矩阵快速幂模板

    矩阵快速幂其实跟普通快速幂一样,只是把数换成矩阵而已。

    模板,两种写法,亲测可用:

    //made by whatbeg
    //2014.6.15
    struct Matrix
    {
        int m[3][3];
    };
    
    Matrix Mul(Matrix a,Matrix b)
    {
        Matrix c;
        memset(c.m,0,sizeof(c.m));
        for(int i=0;i<3;i++)
            for(int j=0;j<3;j++)
                for(int k=0;k<3;k++)
                    c.m[i][j] += ((a.m[i][k]*b.m[k][j])%SMod + SMod)%SMod;
        return c;
    }
    
    Matrix fastm(Matrix a,int n) 
    {
        Matrix res;
        memset(res.m,0,sizeof(res.m));
        res.m[0][0] = res.m[1][1] = res.m[2][2] = 1;
        while(n)
        {
            if(n&1)
                res = Mul(res,a);
            n>>=1;
            a = Mul(a,a);
        }
        return res;
    }
    
    Matrix MPow(Matrix a,int n)  //第二种写法,慎用,易RE
    {
        if(n == 1)
            return a;
        Matrix res = fastm(a,n/2);
        res = Mul(res,res);
        if(n&1)
            res = Mul(res,a);
        return res;
    }

     另一种:

    struct Matrix
    {
        lll m[13][13];
        Matrix()
        {
            memset(m,0,sizeof(m));
            for(int i=1;i<=n+2;i++)
                m[i][i] = 1LL;
        }
    };
    
    Matrix Mul(Matrix a,Matrix b)
    {
        Matrix res;
        int i,j,k;
        for(i=1;i<=n+2;i++)
        {
            for(j=1;j<=n+2;j++)
            {
                res.m[i][j] = 0;
                for(k=1;k<=n+2;k++)
                    res.m[i][j] = (res.m[i][j]+(a.m[i][k]*b.m[k][j])%SMod + SMod)%SMod;
            }
        }
        return res;
    }
    
    Matrix fastm(Matrix a,int b)
    {
        Matrix res;
        while(b)
        {
            if(b&1)
                res = Mul(res,a);
            a = Mul(a,a);
            b >>= 1;
        }
        return res;
    }

     对元素0较多的矩阵取快速幂时可在Mul函数中加一个小优化:

    Matrix Mul(Matrix a,Matrix b)
    {
        Matrix res;
        int i,j,k;
        memset(res.m,0,sizeof(res.m));
        for(k=1;k<=n+2;k++)
        {
            for(i=1;i<=n+2;i++)
            {
                if(a.m[i][k])
                {
                    for(j=1;j<=n+2;j++)
                        res.m[i][j] = (res.m[i][j]+(a.m[i][k]*b.m[k][j])%SMod + SMod)%SMod;
                }
            }
        }
        return res;
    }
  • 相关阅读:
    关键字 final
    继承中的构造方法
    方法的重写
    使用tar 和 split 将文件打包、压缩并分割成指定大小
    标准Web系统的架构分层
    Android的安全机制 1 -- 老罗
    Android 在 SElinux下 如何获得对一个内核节点的访问权限
    移动数据 流程分析
    ARM Linux 3.x的设备树(Device Tree)
    如何分析Android的Log
  • 原文地址:https://www.cnblogs.com/whatbeg/p/3790164.html
Copyright © 2011-2022 走看看