zoukankan      html  css  js  c++  java
  • hdu 1575 Tr A (矩阵快速幂入门题)

    题目

    先上一个链接:十个利用矩阵乘法解决的经典题目

    这个题目和第二个类似

    由于矩阵乘法具有结合律,因此A^4 = A * A * A * A = (A*A) * (A*A) = A^2 * A^2。我们可以得到这样的结论:当n为偶数时,A^n = A^(n/2) * A^(n/2);当n为奇数时,A^n = A^(n/2) * A^(n/2) * A (其中n/2取整)。这就告诉我们,计算A^n也可以使用二分快速求幂的方法。例如,为了算出A^25的值,我们只需要递归地计算出A^12、A^6、A^3的值即可。根据一些结果,我们可以在计算过程中不断取模,避免高精度运算。

    思路:如果直接相乘的话,时间复杂度是O(n*n*k)。

    耗时太长,这里可以采用二分的思想。

    另设置一个b[]数组,存储k为奇数的时候的 a[]矩阵的乘积。

    k为偶数时,直接把a[]相乘,就相当于使k次相乘减少了一半。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 using namespace std;
     6 const int mo = 9973;
     7 int n, ans;
     8 
     9 struct node
    10 {
    11     int m[11][11];
    12 };
    13 node mult(node a, node b)
    14 {
    15     node c;
    16     int i, j, k;
    17     for(i = 1; i <= n; i++)
    18         for(j = 1; j <= n; j++)
    19         {
    20             c.m[i][j] = 0;
    21             for(k = 1; k <= n; k++)
    22                 c.m[i][j] += a.m[i][k]*b.m[k][j];
    23             c.m[i][j] %= mo;
    24         }
    25     return c;
    26 }
    27 int main()
    28 {
    29     node a, b;
    30     int t, k;
    31     int i, j;
    32     cin>>t;
    33     while(t--)
    34     {
    35         ans = 0;
    36         cin>>n>>k;
    37         for(i = 1; i <= n; i++)
    38             for(j = 1; j <= n; j++)
    39             {
    40                 cin>>a.m[i][j];
    41                 if(i == j)
    42                     b.m[i][j] = 1;
    43                 else
    44                     b.m[i][j] = 0;
    45             }
    46         while(k > 1)
    47         {
    48             if(k%2==1)
    49             {
    50                 k--;
    51                 b = mult(a, b);
    52             }
    53             else
    54             {
    55                 k = k/2;
    56                 a = mult(a, a);
    57             }
    58         }
    59         b = mult(a, b);
    60         for(i = 1; i <= n; i++)
    61         {
    62             ans += b.m[i][i];
    63             ans %= mo;
    64         }
    65         cout<<ans<<endl;
    66     }
    67     return 0;
    68 }
  • 相关阅读:
    jQuery插件编写步骤详解
    原生JavaScript实现JSON合并(递归深度合并)
    js原型链继承及调用父类方法
    codefind.pl
    如何为属性是disabled的表单绑定js事件
    平假名、片假名转换
    #和##在宏替换中的作用
    Perl实用中文处理步骤(修改版)
    Perl Unicode全攻略
    nio DirectByteBuffer如何回收堆外内存
  • 原文地址:https://www.cnblogs.com/bfshm/p/3639175.html
Copyright © 2011-2022 走看看