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('\n');
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 } 
矩阵快速幂

这篇博客的程序上做了点修改,感谢!

posted @ 2017-10-01 22:18  lpl_bys  阅读(266)  评论(0编辑  收藏  举报