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 100 101 102 103 104 105 106 107 108 109
|
#include <bits/stdc++.h> using namespace std; #define int long long #define resetIO(x) \ freopen(#x ".in", "r", stdin), freopen(#x ".out", "w", stdout) #define debug(fmt, ...) \ fprintf(stderr, "[%s:%d] " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__) template <class _Tp> inline _Tp& read(_Tp &x) { bool sign = false; char ch = getchar(); long double tmp = 1; for (; !isdigit(ch); ch = getchar()) sign |= (ch == '-'); for (x = 0; isdigit(ch); ch = getchar()) x = x * 10 + (ch ^ 48); if (ch == '.') for (ch = getchar(); isdigit(ch); ch = getchar()) tmp /= 10.0, x += tmp * (ch ^ 48); return sign ? (x = -x) : x; } template <class _Tp> inline void write(_Tp x) { if (x < 0) putchar('-'), x = -x; if (x > 9) write(x / 10); putchar((x % 10) ^ 48); } const int MAXN = 65; const int INFL = 0x3f3f3f3f3f3f3f3f; const int MOD = 1e9 + 7; int n, k, q; char buf[MAXN]; bool mp[MAXN][MAXN]; int dp[2][2][MAXN][MAXN][MAXN], f[2][MAXN][MAXN][MAXN], g[2][MAXN][MAXN][MAXN]; void uadd(int &x, int y) { x += y; if (x >= MOD) x -= MOD; } int query(int s, int t, int bs, int bt) { memset(f[1], 0, sizeof(f[1])); memset(g[1], 0, sizeof(g[1])); memset(dp[0][1], 0, sizeof(dp[0][1])); memset(dp[1][0], 0, sizeof(dp[1][0])); memset(dp[1][1], 0, sizeof(dp[1][1])); for (int c = 1; c <= k; ++c) { for (int y = 1; y <= n; ++y) for (int v = 1; v <= n; ++v) if (mp[v][y]) uadd(f[1][s][y][c], dp[1][0][s][v][c - 1]); for (int x = 1; x <= n; ++x) for (int v = 1; v <= n; ++v) if (mp[x][v]) uadd(g[1][x][t][c], dp[0][1][v][t][c - 1]); if (c == bs) uadd(f[1][s][s][c], 1); if (c == bt) uadd(g[1][t][t][c], 1); for (int v = 1; v <= n; ++v) { dp[1][0][s][v][c] = dp[1][0][s][v][c - 1]; dp[0][1][v][t][c] = dp[0][1][v][t][c - 1]; for (int l = 1; l <= n; ++l) { uadd(dp[1][0][s][v][c], f[1][s][l][c] * g[0][l][v][c] % MOD); uadd(dp[0][1][v][t][c], f[0][v][l][c] * g[1][l][t][c] % MOD); } } dp[1][1][s][t][c] = dp[1][1][s][t][c - 1]; for (int v = 1; v <= n; ++v) uadd(dp[1][1][s][t][c], f[1][s][v][c] * g[1][v][t][c] % MOD); } return dp[1][1][s][t][k]; } signed main() { read(n), read(k), read(q); for (int i = 1; i <= n; ++i) { scanf("%s", buf + 1); for (int j = 1; j <= n; ++j) mp[i][j] = buf[j] - '0'; } for (int c = 1; c <= k; ++c) { for (int x = 1; x <= n; ++x) for (int y = 1; y <= n; ++y) for (int t = 1; t <= n; ++t) if (mp[t][y]) uadd(f[0][x][y][c], dp[0][0][x][t][c - 1]); for (int x = 1; x <= n; ++x) for (int y = 1; y <= n; ++y) for (int t = 1; t <= n; ++t) if (mp[x][t]) uadd(g[0][x][y][c], dp[0][0][t][y][c - 1]); for (int i = 1; i <= n; ++i) uadd(f[0][i][i][c], 1), uadd(g[0][i][i][c], 1); for (int x = 1; x <= n; ++x) for (int y = 1; y <= n; ++y) uadd(dp[0][0][x][y][c], dp[0][0][x][y][c - 1]); for (int x = 1; x <= n; ++x) for (int y = 1; y <= n; ++y) for (int t = 1; t <= n; ++t) uadd(dp[0][0][x][y][c], f[0][x][t][c] * g[0][t][y][c] % MOD); } while (q--) { int bs, s, bt, t; read(bs), read(s), read(bt), read(t); write(query(s, t, bs, bt)), putchar('\n'); } return 0; }
|