zoukankan      html  css  js  c++  java
  • 矩阵快速幂(学习笔记)

    矩阵乘法:设A是(n*m)的矩阵,B是(m*p)的矩阵,则(C=A*B)(n*p)的矩阵,(C_{i,j}=sum_{k=1}^{m} A_{i,k}*B_{k,j})(即矩阵C第i行第j列的数,是由A的第i行的m个数与B的第j列的m个数分别相乘再相加得到的)

    for(int i=1;i<=n;i++)
    	for(int j=1;j<=p;j++)
    		for(int k=1;k<=m;k++)
    			c[i][j]=c[i][j]+a[i][k]*b[k][j];
    

    矩阵中有一类特殊的矩阵,它非常有用,称为单位矩阵.单位矩阵只有对角线上的数字是1,其余都是0,在矩阵乘法中它就相当于1,任何矩阵乘上单位矩阵还是等于本身.

    矩阵快速幂用于求(A^k),其中A是一个矩阵,k是幂.模板还是快速幂的模板,只是快速幂中的"乘号"不再是数字与数字相乘的意思,而是矩阵与矩阵相乘的意思.

    传送门:模板[矩阵快速幂]

    LL mod=1e9+7,n,k;
    struct mat{
        LL jz[105][105];
    }a,b;
    //用结构体来存储矩阵
    //a是读入的矩阵,b是单位矩阵
    mat mul(mat x,mat y){
        mat c;
        for(int i=1;i<=n;i++)
    	for(int j=1;j<=n;j++)
    	    c.jz[i][j]=0;//记得赋初值为0
        for(int i=1;i<=n;i++)
    		for(int j=1;j<=n;j++)
    	    	for(int k=1;k<=n;k++)
    				c.jz[i][j]=c.jz[i][j]%mod+(x.jz[i][k]*y.jz[k][j])%mod;
        return c;
    }
    mat quickpow(mat x,LL y){
        mat cnt=b;
    //本来的快速幂中cnt=1,矩阵快速幂中cnt=单位矩阵b(相当于1)
        while(y){
    		if(y&1)cnt=mul(cnt,x);
    		x=mul(x,x);
    //不再是数字乘数字,而是矩阵乘矩阵
    		y/=2;
        }
        return cnt;
    }
    int main(){
        n=read();k=read();
        for(int i=1;i<=n;i++)
    	for(int j=1;j<=n;j++)
    	    a.jz[i][j]=read();
        for(int i=1;i<=n;i++)b.jz[i][i]=1;
    //构建出单位矩阵
        mat ans=quickpow(a,k);//直接快速幂
        for(int i=1;i<=n;i++){
    		for(int j=1;j<=n;j++)
    	    	printf("%lld ",ans.jz[i][j]%mod);
    		printf("
    ");
        }
        return 0;
    }
    
    
  • 相关阅读:
    OI回忆录
    【CSP2019】题解合集
    微电影《Junior·BQB》——剧本
    【UOJ139】【UER #4】被删除的黑白树
    NOIWC2019 冬眠记
    THUWC2019 划水记
    【XSY3413】Lambda
    【BZOJ3065】带插入区间k小值
    【BZOJ3600】没有人的算术
    【BZOJ4864】【BJWC2017】神秘物质
  • 原文地址:https://www.cnblogs.com/PPXppx/p/10386701.html
Copyright © 2011-2022 走看看