structMatrix { int n; int a[MAXN][MAXN]; Matrix(int n = 0) : n(n) { memset(a, 0, sizeof(a)); }
static Matrix identity(int n){ // 单位矩阵 I Matrix I(n); for (int i = 0; i < n; i++) I.a[i][i] = 1; return I; }
Matrix operator*(const Matrix &B) const { Matrix C(n); for (int i = 0; i < n; i++) for (int k = 0; k < n; k++) { if (!a[i][k]) continue; // 跳过 0,减少无效乘法 int t = a[i][k]; for (int j = 0; j < n; j++) C.a[i][j] = (C.a[i][j] + t * B.a[k][j]) % MOD; } return C; } };
Matrix mt_qmi(Matrix base, int p){ // base 的 p 次幂 Matrix ans = Matrix::identity(base.n); while (p) { if (p & 1) ans = ans * base; base = base * base; p >>= 1; } return ans; }
structMat { int n; int a[MAXN][MAXN]; Mat(int n = 0) : n(n) { memset(a, 0x3f, sizeof(a)); } // 初始化为 INF
Mat operator*(const Mat &B) const { // (min, +) 广义乘法 Mat C(n); for (int i = 0; i < n; i++) for (int k = 0; k < n; k++) { if (a[i][k] == INF) continue; for (int j = 0; j < n; j++) if (B.a[k][j] != INF) C.a[i][j] = min(C.a[i][j], a[i][k] + B.a[k][j]); } return C; } };
Mat mt_qmi(Mat base, int p){ // (min, +) 意义下的 p 次幂 Mat ans(base.n); for (int i = 0; i < base.n; i++) ans.a[i][i] = 0; // 单位元:0 条边 while (p) { if (p & 1) ans = ans * base; base = base * base; p >>= 1; } return ans; }