bzoj 1898 矩阵快速幂
思路:因为鱼的周期为2, 3, 4, 所以以12个为周期,我们拿走12步得到的矩阵进行快速幂,余下的再进行一次矩阵乘法。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PII pair<int, int> #define y1 skldjfskldjg #define y2 skldfjsklejg using namespace std; const int N = 50 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 10000; int n, m, S, T, K, num; int fish[22][4], len[22], p[22]; int ban[N]; vector<int> edge[N]; struct Matrix { int a[50][50], n; Matrix(int _n = 0) { n = _n; memset(a, 0, sizeof(a)); } void init() { for(int i = 0; i < n; i++) a[i][i] = 1; } Matrix operator * (const Matrix &B) const { Matrix C(n); for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) for(int k = 0; k < n; k++) C.a[i][j] = (C.a[i][j] + a[i][k] * B.a[k][j]) % mod; return C; } Matrix operator ^ (int b) { Matrix C(n); C.init(); Matrix A = (*this); while(b) { if(b & 1) C = C * A; A = A * A; b >>= 1; } return C; } }; void nextTime() { for(int i = 0; i < num; i++) { ban[fish[i][p[i]]]--; p[i] = (p[i] + 1) % len[i]; ban[fish[i][p[i]]]++; } } int main() { scanf("%d%d%d%d%d", &n, &m, &S, &T, &K); for(int i = 1; i <= m; i++) { int u, v; scanf("%d%d", &u, &v); edge[u].push_back(v); edge[v].push_back(u); } scanf("%d", &num); for(int i = 0; i < num; i++) { scanf("%d", &len[i]); for(int j = 0; j < len[i]; j++) scanf("%d", &fish[i][j]); ban[fish[i][0]]++; } Matrix B[13]; for(int i = 0; i < 13; i++) B[i].n = n; for(int i = 0; i < n; i++) if(!ban[i]) B[0].a[i][i] = 1; for(int k = 1; k <= 12; k++) { nextTime(); for(int u = 0; u < n; u++) { if(ban[u]) continue; for(int i = 0; i < edge[u].size(); i++) { int v = edge[u][i]; for(int j = 0; j < n; j++) B[k].a[u][j] = (B[k].a[u][j] + B[k - 1].a[v][j]) % mod; } } } Matrix A = B[K % 12] * (B[12] ^ (K / 12)); printf("%d\n", A.a[T][S]); return 0; } /* */