题意
Sol
不难发现吃人鱼的运动每\(12s\)一个周期
所以暴力建12个矩阵,放在一起快速幂即可
最后余下的部分暴力乘
#includeusing namespace std;const int MAXN = 52, mod = 10000;inline int read() { char c = getchar(); int x = 0, f = 1; while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();} while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar(); return x * f;}int N, M, S, T, K, mp[MAXN][MAXN], pos[MAXN];int add(int x, int y) { if(x + y < 0) return x + y + mod; return x + y >= mod ? x + y - mod : x + y;}int add2(int &x, int y) { if(x + y < 0) x = x + y + mod; else x = (x + y >= mod ? x + y - mod : x + y);}int mul(int x, int y) { return 1ll * x * y % mod;}struct Ma { int m[MAXN][MAXN]; Ma() { memset(m, 0, sizeof(m)); } Ma operator * (const Ma &rhs) const { Ma ans; for(int k = 1; k <= N; k++) for(int i = 1; i <= N; i++) for(int j = 1; j <= N; j++) add2(ans.m[i][j], mul(m[i][k], rhs.m[k][j])); return ans; }}a[15], bg;Ma MatrixFp(Ma a, int p) { Ma base; for(int i = 1; i <= N; i++) base.m[i][i] = 1; while(p) { if(p & 1) base = base * a; a = a * a; p >>= 1; } return base;}int main() { N = read(); M = read(); S = read() + 1; T = read() + 1; K = read(); for(int i = 1; i <= M; i++) {int x = read() + 1, y = read() + 1; bg.m[x][y]++; bg.m[y][x]++;} int fn = read(); for(int i = 1; i <= 12; i++) a[i] = bg; for(int i = 1; i <= fn; i++) { int num = read(); for(int j = 1; j <= num; j++) pos[j] = read() + 1; for(int j = 1; j <= 12; j++) for(int k = 1; k <= N; k++) a[j].m[k][pos[j % num + 1]] = 0; } Ma res = a[1]; //for(int i = 1; i <= N; i++) res.m[i][i] = 1; for(int i = 2; i <= 12; i++) res = res * a[i]; res = MatrixFp(res, K / 12); for(int i = 1; i <= K % 12; i++) res = res * a[i]; printf("%d\n", res.m[S][T]); return 0;}/*6 8 1 5 3330 22 11 00 55 11 44 33 533 0 5 12 1 24 1 2 3 4 */