zoukankan      html  css  js  c++  java
  • 51nod 1113 矩阵快速幂 如题目

    基准时间限制:3 秒 空间限制:131072 KB 分值: 40 难度:4级算法题
     
    给出一个N * N的矩阵,其中的元素均为正整数。求这个矩阵的M次方。由于M次方的计算结果太大,只需要输出每个元素Mod (10^9 + 7)的结果。
     
    Input
    第1行:2个数N和M,中间用空格分隔。N为矩阵的大小,M为M次方。(2 <= N <= 100, 1 <= M <= 10^9)
    第2 - N + 1行:每行N个数,对应N * N矩阵中的1行。(0 <= N[i] <= 10^9)
    Output
    共N行,每行N个数,对应M次方Mod (10^9 + 7)的结果。
    Input示例
    2 3
    1 1
    1 1
    Output示例
    4 4
    4 4
    ------------------------------------------------------------

    矩阵乘法+快速幂
    首先要知道矩阵乘法的运算规则:

      矩阵A*矩阵B=矩阵C
    y1=x1t1+x2t3;
    y2=x1t2+x2t4;
    y3=x3t1+x4t3;
    y4=x3t2+x4t4;

    C矩阵(结果矩阵)的第i行第j列的数等于A矩阵第i行的数分别与B矩阵第j列的数的乘积之和
    也可以这样看,A矩阵第i行与B矩阵第j列相交的位置,即计算结果在C矩阵上的位置
    第一次接触矩阵乘法,感觉这个规则有种说不出的奇怪,直到看到这篇博客,加深了我对矩阵乘法的认识。

    知道了矩阵的运算法则后,接下来就是在程序中重载矩阵乘法的一些操作。快速幂当然是在重载矩阵运算符(^)中实现,其实现方法依然可以套用其在普通数据类型中的方法(思路都是一样的)。

    详细看代码:

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<iostream>
     4 #define maxn 110
     5 #define mod 1000000007
     6 using namespace std;
     7 struct matrix{       
     8     long long m[maxn][maxn];//切记开longlong,不然会爆    
     9 int read();
    10 matrix operator * (matrix,matrix);
    11 matrix operator ^ (matrix,int);
    12 int N,M;
    13 int main(){
    14     N=read();M=read();
    15     matrix x,a;
    16     for(int i=1;i<=N;i++)
    17        for(int j=1;j<=N;j++)
    18           x.m[i][j]=read();
    19     a=x^M;
    20     for(int i=1;i<=N;i++){
    21         for(int j=1;j<=N;j++)
    22           printf("%lld ",a.m[i][j]);
    23         putchar('
    ');
    24     }
    25     return 0;
    26 } 
    27 int read(){
    28     int ans=0,f=1;char c=getchar();
    29     while('0'>c||c>'9'){if(c=='-')f=-1;c=getchar();}
    30     while('0'<=c&&c<='9')ans=ans*10+c-48,c=getchar();return ans*f;
    31 }
    32 matrix operator * (const matrix a,const matrix b){ //重载乘法 
    33     matrix an;
    34     memset(an.m,0,sizeof(an.m));
    35     for(int i=1;i<=N;i++)
    36        for(int j=1;j<=N;j++)
    37           for(int k=1;k<=N;k++){
    38               an.m[i][j]+=a.m[i][k]*b.m[k][j]%mod;
    39               an.m[i][j]%=mod;          
    40         }
    41     return an;
    42 }
    43 matrix operator ^ (matrix a,int b){  //重载幂运算
    44     matrix an;
    45     for(int i=1;i<=N;i++)     //初始化an,即累乘变量
    46        for(int j=1;j<=N;j++)
    47           an.m[i][j]=(i==j);  //注意这里应为i==j,而不是1,跟矩阵的运算法则有关吧
    48     while(b){  //快速幂
    49         if(b&1) an=an*a;
    50         a=a*a;
    51         b>>=1;
    52     }
    53     return an;
    54 } 
    矩阵快速幂
    
    
    这篇博客的程序上做了点修改,感谢!

  • 相关阅读:
    [LOJ2288][THUWC2017]大葱的神力:搜索+背包DP+费用流+随机化
    [省选练习]S
    [省选练习]P
    动态淀粉质(划掉)题单&简要题解
    [CF1093G]Multidimensional Queries:线段树
    [BZOJ3199][SDOI2013]escape:半平面交
    计算几何模板
    [洛谷P5106]dkw的lcm:欧拉函数+容斥原理+扩展欧拉定理
    [POJ1637]Sightseeing tour:混合图欧拉回路
    重复旋律:后缀数组+后缀自动机
  • 原文地址:https://www.cnblogs.com/lpl-bys/p/7618027.html
Copyright © 2011-2022 走看看