P3390 【模板】矩阵快速幂(Java&C++)
发布日期:2021-05-08 22:12:49 浏览次数:18 分类:精选文章

本文共 1932 字,大约阅读时间需要 6 分钟。

为了解决矩阵快速幂问题,我们可以使用矩阵乘法和快速幂结合的方法。快速幂算法可以将矩阵指数iation的时间复杂度从O(n^3 * k)减少到O(n^3 * log k),大大提高效率。

方法思路

  • 矩阵乘法:定义一个函数进行矩阵相乘,确保每一步都对结果取模,避免数值溢出。
  • 快速幂算法:使用快速幂分治方法,将矩阵的指数计算转化为多次矩阵乘法和平方运算。每次处理矩阵的最低有效位,按位处理k。
  • 初始化单位矩阵:如果k为0,结果为单位矩阵,否则初始化结果为输入矩阵,进行快速幂运算。
  • 解决代码

    import java.util.Scanner;
    public class Main {
    static int n;
    static final long mod = 1000000007;
    public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    n = sc.nextInt();
    long m = sc.nextLong();
    long[][] a = new long[n + 1][n + 1];
    for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) {
    a[i][j] = sc.nextLong() % mod;
    }
    }
    ksm(a, m);
    }
    private static void ksm(long[][] a, long m) {
    long[][] ans = new long[n + 1][n + 1];
    for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) {
    ans[i][j] = 1;
    }
    }
    while (m != 0) {
    if ((m & 1) != 0) {
    ans = mul(ans, a);
    m--;
    } else {
    a = mul(a, a);
    m >>= 1;
    }
    }
    for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) {
    System.out.print(ans[i][j] + " ");
    }
    System.out.println();
    }
    }
    private static long[][] mul(long[][] a, long[][] b) {
    long[][] c = new long[n + 1][n + 1];
    for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) {
    for (int k = 1; k <= n; k++) {
    c[i][j] = (c[i][j] + (a[i][k] * b[k][j])) % mod;
    }
    }
    }
    return c;
    }
    }

    代码解释

  • 输入处理:读取输入的矩阵大小n以及幂指数k,读取矩阵数据并进行模运算处理。
  • 单位矩阵初始化:在快速幂计算开始前,初始化结果矩阵为单位矩阵,以处理k=0的情况。
  • 快速幂循环:处理k的二进制位,根据当前位是否为1,决定是否需要执行矩阵相乘并进行幂运算。
  • 矩阵乘法:定义一个函数进行矩阵相乘,确保每一步乘法操作都对结果取模。
  • 该方法确保了在处理大指数时的效率,同时正确处理模运算,防止数值溢出。

    上一篇:HDU Encoding(字符串)
    下一篇:ASP.NET jQuery 小实例(实现图片的放大&缩小)

    发表评论

    最新留言

    哈哈,博客排版真的漂亮呢~
    [***.90.31.176]2025年04月02日 12时10分15秒