矩阵快速幂

学快速幂时,做到了矩阵快速幂,就学习了一下矩阵乘法,今天又碰到了一个关于矩阵乘法的问题,就顺便整理复习一下。

快速幂

快速幂顾名思义就是让乘方运算更加快速的算法,n^x这样的乘方运算本来是要n*n*n*……*n(共x个n)这样一个一个运算,但快速幂的思想是将n分成2的多次方和,如2^34=2^32*2^2,呈现方式是通过二分,如2^34=(2^17)^2=(2^16*2)^2=((((2^2)^2)^2)^2*2)^2

long long ksm(int n,int x){
    if(x==0) return 1;
    long long ans=ksm(n,x/2);
    ans*=ans;
    if(x%2==1) ans*=n;
    return ans;
}

矩阵乘法

矩阵乘法就是一个m*n的矩阵A乘一个n*p的矩阵B得到一个m*p的矩阵C

这样看矩阵乘法只有结合律,没有交换律

C[i][j]=a[i][1]*b[1][j]+a[i][2]*b[2][j]+……+a[i][n]*b[n][j]

例如:A=|1 2 3|

     |4 5 6|

   B=|1 5|

     |3 7|

     |2 4|

   C=A*B=|1*1+2*3+3*2 1*5+2*7+3*4|=|13 31|

        |1*4+3*5+2*6 4*5+5*7+6*4|  |31 79|

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

矩阵快速幂

矩阵快速幂就是矩阵乘法和快速幂的结合

int ans[101][101];
void jzksm(int a[101][101],int n){
    if(n==1){
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                ans[i][j]=a[i][j];
            }
        }
        return ;
    }
    jzksm(a,n/2);
    int t[101][101];
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            for(int k=1;k<=n;k++){
                t[i][j]+=ans[i][k]*ans[k][j];
            }
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            ans[i][j]=t[i][j];
            t[i][j]=0;
        }
    }
    if(n%2==1){
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                for(int k=1;k<=n;k++){
                    t[i][j]+=ans[i][k]*a[k][j];
                }
            }
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                ans[i][j]=t[i][j];
                t[i][j]=0;
            }
        }
    }
}

 

posted @ 2022-02-10 19:31  zzzzzz2  阅读(61)  评论(0编辑  收藏  举报