ATC DP R Walk
https://atcoder.jp/contests/dp/tasks/dp_r
这里 A n A^n An中, A [ i ] [ j ] A[i][j] A[i][j]表示的是从i出发走到点j走n步,有多少种走法。
理解的话看这里:https://blog.csdn.net/u011251225/article/details/44421853
感谢这位dalao
#include <iostream>
#include <cstdio>
using namespace std;
const int N = 100;
const int mod = 1e9 + 7;
typedef long long ll;
ll mp[N][N];
ll tmp[N][N];
void multi(ll a[][N], ll b[][N], ll n) {
memset(tmp, 0, sizeof tmp);
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
for (int k = 0; k < n; k++) {
tmp[i][j] += a[i][k] * b[k][j];
tmp[i][j] %= mod;
}
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
a[i][j] = tmp[i][j];
}
}
}
ll res[N][N];
void Pow(ll a[][N], ll n, ll lim) {
memset(res, 0, sizeof res);
for (int i = 0; i < lim; i++) res[i][i] = 1;
while (n) {
if (n & 1) {
multi(res, a, lim);
}
multi(a, a, lim);
n >>= 1;
}
}
int main() {
ll n, k;
cin >> n >> k;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> mp[i][j];
}
}
Pow(mp, k, n);
ll ans = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
ans += res[i][j];
ans %= mod;
}
}
cout<<ans<<endl;
return 0;
}