合抱之木,生于毫末;九层之台,起于垒土;千里之行,始于足下。为者败之,执者失之。
洛谷p3390 时间复杂度 o(n ^ 3 log n ) ;
#include<bits/stdc++.h>
using namespace std ;
typedef long long LL ;
const int mod = 1e9+7 ;
LL n , k ;
struct matrix
{
LL c[105][105] ;
matrix(){memset(c,0,sizeof c );}
}res,A;
matrix operator*(const matrix &x , const matrix & y )
{
matrix t ;
for(int i = 1 ; i <= n ; i ++ )
for(int j = 1 ; j <= n ; j ++ )
for(int k = 1 ; k <= n ; k ++ )
t.c[i][j]=(t.c[i][j] + x.c[i][k]*y.c[k][j])%mod;
return t ;
}
void quickpow()
{
for(int i = 1 ; i <= n ; i ++ ) res.c[i][i] = 1 ;
while(k)
{
if(k&1) res = res * A ;
A = A * A ;
k >>= 1 ;
}
for(int i = 1 ; i <= n ; i ++ )
{
for(int j = 1 ; j <= n ; j ++ )
{
cout << res.c[i][j]<<" " ;
}
cout <<endl ;
}
}
int main()
{
ios::sync_with_stdio(false) ;
cin.tie(0);
cout.tie(0);
cin >> n >> k ;
for(int i = 1 ; i <= n ; i ++ )
{
for(int j = 1 ; j <= n ; j ++ )
{
cin >> A.c[i][j] ;
}
}
quickpow();
return 0 ;
}
在矩阵的乘法中运用了重载运算符,在C++中,
operator*
是一个特殊的操作符重载函数,它允许你自定义当使用*
操作符在两个对象之间进行乘法运算时的行为。当你定义这样的函数时,你实际上是在告诉编译器:“当有人尝试使用*
操作符来乘以两个matrix
类型的对象时,请使用这个函数来执行乘法操作。”
在C++中,当你为某个自定义类型(如
matrix
类)重载了operator*
后,这并不会影响内置类型(如int
、float
等)之间的*
操作符的行为。也就是说,你仍然可以像平常一样使用*
来乘以两个内置类型的值,如1 * 2
,这将会返回2
。
重载的
operator*
只会影响你为其定义的类型(在这个例子中是matrix
类)之间的乘法操作。因此,当你使用matrix
对象进行乘法时,如matrix a, b, c; c = a * b;
,编译器会调用你定义的operator*
函数来执行矩阵乘法。
在这个快速幂模板中定义的res是一个单位矩阵,就相当于普通的快速幂中的1;