矩阵快速幂

快速幂基础
https://www.cnblogs.com/CXCXCXC/p/4641812.html

矩阵快速幂的基础
https://blog.csdn.net/wust_zzwh/article/details/52058209


  • 矩阵快速幂,顾名思义就是加快矩阵求幂。
  • 所有满足结合率的运算都可以用矩阵快速幂

先来一个矩阵快速幂的裸题:
https://vjudge.net/problem/POJ-3233

矩阵快速幂的步骤:

  1. 写出转移方程
    在这里插入图片描述
  2. 转移矩阵
    在这里插入图片描述
  3. 利用矩阵快速幂求解

Java 源代码

import java.util.*;

public class Main{
    
    private static long[][] data = new long [40][40];
    private static long[][] matrix = new long [80][80]; 

    private static long[][] multiply(long[][] a, long[][] b,int n,int mod){

        long[][] result = new long[80][80];
        for(int i=1;i<=2*n;i++){
            for(int j=1;j<=2*n;j++){
                for(int k=1;k<=2*n;k++){
                    result[i][j] += ((a[i][k]*b[k][j])%mod);
                    result[i][j] %=mod;
                }
            }
        }

        return result;
    }

    private static long[][] quick(int k,int n,int mod){

    
        long[][] cur = new long[80][80];
        long[][] result = new long[80][80];
        for(int i=1;i<=2*n;i++){
            result[i][i]=1;
        }
        cur = matrix;
    

        while(k!=0){
    
            if(k%2 ==1) result = multiply(result, cur, n, mod);

            cur = multiply(cur, cur, n, mod);
            k/=2;
        }

        return result;

    }

 public static void main(String arg[]){
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int k = in.nextInt();
        int m = in.nextInt();
        

        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                data[i][j]=in.nextInt();
                matrix[i][j]=data[i][j];
            }
        }

        in.close();

        //to the matrix
        for(int i=1;i<=n;i++){
            for(int j=n+1;j<=2*n;j++){
                matrix[i][j] = data[i][j-n];
            }
        }
        for(int i=n+1;i<=2*n;i++){
            matrix[i][i] = 1;
        }

        long[][] s1 = new long [80][80];
        for(int i=1;i<=2*n;i++){
            for(int j=1;j<=n;j++){
                s1[i][j] = matrix[i][j+n];
            }
        }
        



        matrix=quick(k-1,n,m);

        s1 = multiply(matrix, s1, n, m);

        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                System.out.print(s1[i][j]+" ");
            }
            System.out.println();
        }

    }

}

cpp代码

#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#define NN 100
using namespace std;

int n,k,m;

class Node{
    public:
        long long matrix[NN][NN];

        Node(){
            memset(matrix,0,sizeof(matrix));
        }
};
Node base,result,ende;


Node mul(Node &a,Node &b){
    Node res;
    for(int i=0;i<2*n;i++){
        for(int j=0;j<2*n;j++){
            for(int k=0;k<2*n;k++){
                res.matrix[i][j] += (a.matrix[i][k]*b.matrix[k][j])%m;
                res.matrix[i][j] %=m;
            }
        }
    }
    return res;
}

void quick_multiply(){
    k--;
    for(int i=0;i<NN;i++)
        for(int j=0;j<NN;j++){
            if(i==j) result.matrix[i][j] = 1;
            else result.matrix[i][j] =0;
        }

    while(k){
        if(k&1==1) result = mul(base,result);
        base = mul(base,base);
        k>>=1;
    }

    Node sss = mul(result,ende);

    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            cout<<sss.matrix[i][j]<<" ";
        }
        cout<<endl;
    }

}

void get_data(){
    cin>>n>>k>>m;
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(i==j) base.matrix[i][j] = 1;
            cin>>base.matrix[i][j+n];
            base.matrix[i+n][j+n] = base.matrix[i][j+n];

            ende.matrix[i][j] = base.matrix[i][j+n];
            ende.matrix[i+n][j] = base.matrix[i][j+n];
        }
    }


}

int main(){
    get_data();
    quick_multiply();

    return 0;
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值