[SCOI2009]迷路
[SCOI2009]迷路
思考过程
这个东西发现距离只有 $9$,记得 $\tt Lcm(1 \dots 9) = 2520$ 那么直接考虑暴力处理出来,之后对于每个 $T$ 进行分开计算即可。
显然这个很难写,但是同样是因为距离是 $9$ 那么我们每次只能对于 $T$ 增加 $1$ 不妨考虑直接对于每个点拆开计算。
题解 发现这个 $n$ 特别小,进行拆点矩阵快速幂,这里有几个细节就是因为是单向边,对于拆开的点肯定是距离小的连向距离大的。
这边给不是对于矩阵理解很清晰的神仙讲一下矩阵的细节:
笔者的写法是 $f_i$ 表示从 $0$ 开始到达点 $i$ 的方案数。
之后拆点之后也是如此,那么开始的矩阵就是: $$ \left[ \begin{matrix} f_{0, 1} & f_{0, 2} & \dots & f_{0, 9} & f_{1, 1} & \dots & f_{n - 1, 9} \end{matrix} \right] $$ 之后考虑转移系数矩阵 $G$,对于 $i \to j$ 的转移系数的位置是 $G(i, j)$,那么如果有边就直接为 $1$ 即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 #include <bits/stdc++.h> using namespace std;#define Getmod #ifdef Fread char buf[1 << 21 ], *iS, *iT;#define gc() (iS == iT ? (iT = (iS = buf) + fread (buf, 1, 1 << 21, stdin), (iS == iT ? EOF : *iS ++)) : *iS ++) #define getchar gc #endif template <typename T>void r1 (T &x) { x = 0 ; char c (getchar()) ; int f (1 ) ; for (; c < '0' || c > '9' ; c = getchar ()) if (c == '-' ) f = -1 ; for (; '0' <= c && c <= '9' ;c = getchar ()) x = (x * 10 ) + (c ^ 48 ); x *= f; } template <typename T,typename ... Args> inline void r1 (T& t, Args&... args) { r1 (t); r1 (args...); } #ifdef Getmod const int mod = 2009 ;template <int mod>struct typemod { int z; typemod (int a = 0 ) : z (a) {} inline int inc (int a,int b) const {return a += b - mod, a + ((a >> 31 ) & mod);} inline int dec (int a,int b) const {return a -= b, a + ((a >> 31 ) & mod);} inline int mul (int a,int b) const {return 1ll * a * b % mod;} typemod<mod> operator + (const typemod<mod> &x) const {return typemod (inc (z, x.z));} typemod<mod> operator - (const typemod<mod> &x) const {return typemod (dec (z, x.z));} typemod<mod> operator * (const typemod<mod> &x) const {return typemod (mul (z, x.z));} typemod<mod>& operator += (const typemod<mod> &x) {*this = *this + x; return *this ;} typemod<mod>& operator -= (const typemod<mod> &x) {*this = *this - x; return *this ;} typemod<mod>& operator *= (const typemod<mod> &x) {*this = *this * x; return *this ;} int operator == (const typemod<mod> &x) const {return x.z == z;} int operator != (const typemod<mod> &x) const {return x.z != z;} }; typedef typemod<mod> Tm;#endif const int maxn = 90 + 5 ;const int N = 90 ;typedef long long ll;int n, m;char s[maxn];ll T; #define id(x, y) ( (x - 1) * 9 + y ) struct Matrix { int a[maxn][maxn]; Matrix (void ) { memset (a, 0 , sizeof (a)); } Matrix operator * (const Matrix &z) const { Matrix res; for (int i = 1 ; i <= N; ++ i) for (int j = 1 ; j <= N; ++ j) { for (int k = 1 ; k <= N; ++ k) { res.a[i][j] = (res.a[i][j] + a[i][k] * z.a[k][j]) % mod; } } return res; } }G, F; void ksm (Matrix &res, Matrix tmp,int mi) { while (mi) { if (mi & 1 ) res = res * tmp; mi >>= 1 ; tmp = tmp * tmp; } } signed main () { int i, j; r1 (n, T); for (i = 1 ; i <= n; ++ i) for (j = 2 ; j <= 9 ; ++ j) G.a[id (i, j - 1 )][id (i, j)] = 1 ; for (i = 1 ; i <= n; ++ i) { scanf ("%s" , s + 1 ); for (j = 1 ; j <= n; ++ j) if (s[j] != '0' ) { int x = s[j] ^ 48 ; G.a[id (i, x)][id (j, 1 )] = 1 ; } } F.a[1 ][1 ] = 1 ; ksm (F, G, T); int ans = F.a[1 ][id (n, 1 )]; printf ("%d\n" , ans); return 0 ; }