矩阵快速幂

最近学数学学的比较多,矩阵快速幂应该算数学吧。
题目链接

题目大意:

给定\(n\)\(k\),然后给定\(n \times n\)的矩阵A,求\(A^k\)

数据范围:

\(1\le n \le 100,0 \le q \le 10^12,\vert A_{i,j} \vert \le 1000\)

做法就和快速幂没什么区别,把\(k\)进行二进制拆分,然后快速幂模板
\(k\)开了long long,读入用的%d,一直没看出来,拖了好久[貌似是重构之后发现的]
看到\(k\)的范围,请大家一定记住:

\(1\) \(0\)\(O\) \(I\) 一 场 空 , 不 开 \(l\) \(o\) \(n\) \(g\) \(l\) \(o\) \(n\) \(g\) 见 祖 宗 。

long long re=1;
for(;power;power>>=1,base=base*base){
    if(power&1)re=re*base;//for循环甚至可以压到一行
}
return re;

只不过这里的\(base\)乘不再是一个数,而是一个矩阵,\(mat\)也一样,需要注意的是,在矩阵里\(1\)代表的是单位矩阵,所以注意返回值要初始化成单位矩阵[对角线都是\(1\)].剩下的矩阵乘法就行了
以下是模板

struct Matrix{//结构体
    ll a[N][N];//ll就是long long

    Matrix(){
        memset(a,0,sizeof(a));//一旦定义,初始化为这样
    }

    void scan(){
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                in(a[i][j]);//读入矩阵,n开的全局变量,不需要矩阵里自己存
    }

    void init(){
        for(int i=1;i<=n;i++)
            a[i][i]=1;//init有初始化的意思,这里是单位矩阵初始化
    }

    void print(){
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++)
                out(a[i][j]);//输出
            putchar(10);//10在ASCII码中是换行,32是空格
        }
    }

    Matrix operator * (const Matrix &b)const{//重载乘法为矩阵乘法
        Matrix ret;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                for(int u=1;u<=n;u++)
                    ret.a[i][j]=(ret.a[i][j]+(a[i][u]*b.a[u][j])%md)%md;//矩阵乘的定义,i行j列的数,是前一个矩阵第i行乘后一个第j列
        return ret;
    }
}mat,base;

主函数:

int main(){
    in(n),in(k);
    base.scan();mat.init();//mat就是ans,base就是底数
    MQP(k);//Matrix Quick Power 矩阵 快速 乘方
    mat.print();//输出
    return 0;
}
posted @ 2020-10-13 21:17  Z_char  阅读(145)  评论(0编辑  收藏  举报