
这个题根据题目也就能知道应该怎么做,但是代码怎么实现矩阵乘法,是一个问题,所以就用到了重载运算符。
重载运算符可以定义一些普通的运算,比如 + ,-,×,÷,%,<,>,!=,……有很多,但不能自己创造符号。
在这个题中,需要定义矩阵乘法,在定义之前,还要定义一个结构体:
1 struct hls{
2 long long s[110][110];
3 };
4 hls t,r;
5 long long k;
6 int n;
7 const long long m=1000000007;
8 hls operator * (const hls &a,const hls &b)
9 {
10 hls w;
11 for(int i=1;i<=n;++i)
12 {
13 for(int j=1;j<=n;++j)
14 {
15 w.s[i][j]=0;
16 }
17 }
18 for(int x=1;x<=n;++x)
19 {
20 for(int y=1;y<=n;++y)
21 {
22 for(int z=1;z<=n;++z)
23 {
24 w.s[x][y]+=a.s[x][z]*b.s[z][y]%m;
25 w.s[x][y]%=m;
26 }
27 }
28 }
29 return w;
30 }
结构体中包含一个二维数组,用来表示矩阵。其中第8行之后就是定义重载运算符 * 的代码。
重载运算符语法格式:返回类型(结构体),operator ,定义的符号,后面的括号内再写相应的参数。
比如代码中的a,b。在前面要加 取址符 &,因为如果不加,在程序中就会自行复制 a‘和b’,这样就相当于又开了两个二维数组,不仅耗内存,而且浪费时间。
在大括号内(9—30行)在其中定义结构体 w,用来存储运算后的结果,首先将其清零,接下来用三个for循环,来进行矩阵的乘法运算,
w.s[x][y]就是w结构体中数组第x行,y列的位置,所以在矩阵乘法中,w.s[x][y]的结果就是 a.s的第x行依次与b.s的第y列相乘。所以用三个循环就可以定义矩阵乘法。
m的值为1e9+7,题目要求每个元素对1e9+7取模,所以乘法中应该每步都取模,防止数太大。
重载运算符定义好后,就到了快速幂:
1 for(int i=1;i<=n;++i)
2 {
3 r.s[i][i]=1;
4 }
5 while(k>0)
6 {
7 if(k%2==1) r=r*t;
8 t=t*t;
9 k/=2;
10 }
r是一个单位矩阵,k是指数,while中因为r,t都是hls类型的,所以会自动调用重载运算符。
最终,r 就是结果,输出 r 就可以。
完整代码:
1 #include<iostream>
2 using namespace std;
3 struct hls{
4 long long s[110][110];
5 };
6 hls t,r;
7 long long k;
8 int n;
9 const long long m=1000000007;
10 hls operator * (const hls &a,const hls &b)
11 {
12 hls w;
13 for(int i=1;i<=n;++i)
14 {
15 for(int j=1;j<=n;++j)
16 {
17 w.s[i][j]=0;
18 }
19 }
20 for(int x=1;x<=n;++x)
21 {
22 for(int y=1;y<=n;++y)
23 {
24 for(int z=1;z<=n;++z)
25 {
26 w.s[x][y]+=a.s[x][z]*b.s[z][y]%m;
27 w.s[x][y]%=m;
28 }
29 }
30 }
31 return w;
32 }
33 int main()
34 {
35 cin>>n>>k;
36 for(int i=1;i<=n;++i)
37 {
38 for(int j=1;j<=n;++j)
39 {
40 cin>>t.s[i][j];
41 }
42 }
43 for(int i=1;i<=n;++i)
44 {
45 r.s[i][i]=1;
46 }
47 while(k>0)
48 {
49 if(k%2==1) r=r*t;
50 t=t*t;
51 k/=2;
52 }
53 for(int i=1;i<=n;++i)
54 {
55 for(int j=1;j<=n;++j)
56 {
57 cout<<r.s[i][j]<<" ";
58 }
59 cout<<endl;
60 }
61 return 0;
62 }
来源:https://www.cnblogs.com/zkw666/p/12454946.html