模板裸题
矩阵快速幂
借用了 zngg 的矩阵乘,写个快速幂就好了
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int MAX_MAT = 20;
const ll mod = 9973;
int T, n, k;
struct Mat{
ll a[MAX_MAT][MAX_MAT];
Mat(){
for(int i = 0; i < MAX_MAT; i++){
for(int j = 0; j < MAX_MAT; j++)
a[i][j] = 0;
a[i][i] = 1;
}
}
};
ll quickpow(ll x, ll y, ll MOD){
ll ans = 1;
while(y){
if (y & 1)
ans = (x * ans) % MOD;
x = (x * x) % MOD;
y >>= 1;
}
return ans;
}
ll A[MAX_MAT][MAX_MAT << 1];
ll get_inv(ll x){
return quickpow(x, mod - 2, mod);
}
void row_minus(int a, int b, ll k){
for(int i = 0; i < 2 * MAX_MAT; i++)
A[a][i] = (A[a][i] - A[b][i] * k % mod) % mod, A[a][i] = (A[a][i] + mod) % mod;
}
void row_multiplies(int a, ll k){
for(int i = 0; i < 2 * MAX_MAT; i++)
A[a][i] = (A[a][i] * k) % mod;
}
void row_swap(int a, int b){
for(int i = 0; i < 2 * MAX_MAT; i++)
swap(A[a][i], A[b][i]);
}
Mat getinv(Mat x){
memset(A, 0, sizeof(A));
for(int i = 0; i < MAX_MAT; i++)
for(int j = 0; j < MAX_MAT; j++)
A[i][j] = x.a[i][j], A[i][MAX_MAT + j] = (i == j);
for(int i = 0; i < MAX_MAT; i++){
if (!A[i][i]){
for(int j = i + 1; j < MAX_MAT; j++)
if (A[j][i]){
row_swap(i, j);
break;
}
}
row_multiplies(i, get_inv(A[i][i]));
for(int j = i + 1; j < MAX_MAT; j++)
row_minus(j, i, A[j][i]);
}
for(int i = MAX_MAT - 1; i >= 0; i--)
for(int j = i - 1; j >= 0; j--)
row_minus(j, i, A[j][i]);
Mat ret;
for(int i = 0; i < MAX_MAT; i++)
for(int j = 0; j < MAX_MAT; j++)
ret.a[i][j] = A[i][MAX_MAT + j];
return ret;
}
Mat operator * (Mat x, Mat y){
Mat c;
for(int i = 0; i < MAX_MAT; i++)
for(int j = 0; j < MAX_MAT; j++)
c.a[i][j] = 0;
for(int i = 0; i < MAX_MAT; i++)
for(int j = 0; j < MAX_MAT; j++)
for(int k = 0; k < MAX_MAT; k++)
c.a[i][j] = (c.a[i][j] + x.a[i][k] * y.a[k][j] % mod) % mod;
return c;
}
Mat Mat_quickpow(Mat A, ll k){
Mat ret;
while(k){
if (k & 1)
ret = ret * A;
A = A * A;
k >>= 1;
}
return ret;
}
int main(){
//freopen("input.txt", "r", stdin);
scanf("%d", &T);
Mat A, Ak;
ll sum;
while(T--){
scanf("%d%d", &n, &k);
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
scanf("%lld", &A.a[i][j]);
Ak = Mat_quickpow(A, k);
sum = 0;
for(int i = 0; i < n; i++)
sum = (sum + Ak.a[i][i]) % mod;
printf("%lld\n", sum);
}
return 0;
}



京公网安备 11010502036488号