矩阵乘法以及矩阵快速幂模板

两矩阵 A * B ,当 A 的行数等于 B 的列数时,A * B 合法,结果如下:

 1 #include<stdio.h>

 2 #include<string.h>

 3 typedef long long ll;

 4 const int mod=10000007;

 5 

 6 struct mat{

 7     int r,c;          //r即row,矩阵行数;c即column,矩阵列数

 8     ll m[10][10];    //矩阵

 9     void clear(){    //归零函数

10     for(int i=1;i<=r;i++)memset(m[i],0,sizeof(m[i]));

11     }

12 };

13 

14 mat MatMul(mat m1,mat m2){    //仅当m1.r==m2.c时可以相乘,相乘时可加模运算

15     mat tmp;

16     tmp.r=m1.r;        //计算结果的行数与m1行数相等,列数与m2列数相等

17     tmp.c=m2.c;

18     int i,j,k;

19     for(i=1;i<=tmp.r;i++){

20         for(j=1;j<=tmp.c;j++){

21             ll t=0;

22             for(k=1;k<=m1.c;k++){

23                 t=(t+(m1.m[i][k]*m2.m[k][j])%mod)%mod;

24             }

25             tmp.m[i][j]=t;

26         }

27     }

28     return tmp;

29 }

30 

31 int main(){

32     int t;

33     while(scanf("%d",&t)!=EOF){

34         mat m[2];

35         for(int i=0;i<=1;i++){

36             scanf("%d%d",&m[i].r,&m[i].c);

37             for(int j=1;j<=m[i].r;j++){

38                 for(int k=1;k<=m[i].c;k++){

39                     scanf("%lld",&m[i].m[j][k]);

40                 }

41             }

42         }

43         mat ans=MatMul(m[0],m[1]);

44         for(int i=1;i<=ans.r;i++){

45             for(int j=1;j<=ans.r;j++){

46                 printf("%lld ",ans.m[i][j]);

47             }

48             printf("\n");

49         }

50     }

51     return 0;

52 }

 

 

在之前的矩阵乘法的基础上,引入快速幂的思想,就得到了矩阵的快速幂算法(MatQP,计算矩阵 a 的 n 次幂):

经过修改,把矩阵加法、乘法、快速幂全部重载了一下,写了构造函数,其中矩阵快速幂支持0次幂等于单位矩阵:

 1 #include<stdio.h>

 2 #include<string.h>

 3 #include<math.h>

 4 typedef long long ll;

 5 int mod;

 6 

 7 struct mat{

 8     int r,c;

 9     ll m[4][4];        //经测试最大开成590*590的 ll 型矩阵

10     mat(){}

11     mat(int r,int c):r(r),c(c){}

12     void clear(){

13         memset(m,0,sizeof(m));

14     }

15 

16     mat operator+(mat a)const{

17         mat ans(r,c);

18         for(int i=1;i<=r;i++){

19             for(int j=1;j<=c;j++){

20                 ans.m[i][j]=(m[i][j]+a.m[i][j])%mod;

21             }

22         }

23         return ans;

24     }

25 

26     mat operator*(mat a)const{

27         mat tmp(r,a.c);

28         int i,j,k;

29         for(i=1;i<=tmp.r;i++){

30             for(j=1;j<=tmp.c;j++){

31                 tmp.m[i][j]=0;

32                 for(k=1;k<=c;k++){

33                     tmp.m[i][j]=(tmp.m[i][j]+(m[i][k]*a.m[k][j])%mod)%mod;

34                 }

35             }

36         }

37         return tmp;

38     }

39 

40     mat operator^(int n)const{        //需要时可以用 ll n,注意运算符优先级比较低,多用括号;

41         mat ans(r,r),tmp(r,r);

42         memcpy(tmp.m,m,sizeof(tmp.m));

43         ans.clear();

44         for(int i=1;i<=ans.r;i++){

45             ans.m[i][i]=1;

46         }

47         while(n){

48             if(n&1)ans=ans*tmp;

49             n>>=1;

50             tmp=tmp*tmp;

51         }

52         return ans;

53     }

54     

55     void print()const{

56         for(int i=1;i<=r;i++){

57             for(int j=1;j<=c;j++){

58                 printf("%lld",m[i][j]);

59                 if(j==c)printf("\n");

60                 else printf(" ");

61             }

62         }

63     }

64 

65 };

 

你可能感兴趣的:(模板)