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 110 111 112 113 114
| #include <bits/stdc++.h>
#define int int64_t
const int kMaxN = 205;
int n, m, k, mod; int fa[kMaxN * kMaxN]; std::string s[kMaxN];
int getid(int x, int y) { return (x - 1) * (m + 1) + y; } int getpos(std::vector<int> &v, int x) { return std::lower_bound(v.begin(), v.end(), x) - v.begin() + 1; }
int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); } bool unionn(int x, int y) { int fx = find(x), fy = find(y); if (fx != fy) return fa[fx] = fy, 1; else return 0; }
constexpr int qpow(int bs, int64_t idx = mod - 2) { int ret = 1; for (; idx; idx >>= 1, bs = (int64_t)bs * bs % mod) if (idx & 1) ret = (int64_t)ret * bs % mod; return ret; }
inline int add(int x, int y) { return (x + y >= mod ? x + y - mod : x + y); } inline int sub(int x, int y) { return (x >= y ? x - y : x - y + mod); } inline void inc(int &x, int y) { (x += y) >= mod ? x -= mod : x; } inline void dec(int &x, int y) { (x -= y) < 0 ? x += mod : x; }
struct Matrix { int n, a[kMaxN][kMaxN];
void set(int _n) { n = _n; } void add(int u, int v) { inc(a[u][u], 1), inc(a[v][v], 1), dec(a[u][v], 1), dec(a[v][u], 1); }
int getdet() { if (n > k + 1) return 0; int ret = 1; for (int i = 1; i < n; ++i) { if (!a[i][i]) { for (int j = i + 1; j <= n; ++j) { if (a[j][i]) { std::swap(a[i], a[j]), ret = sub(0, ret); break; } } } ret = 1ll * ret * a[i][i] % mod; for (int j = i + 1; j <= n; ++j) { int d = 1ll * a[j][i] * qpow(a[i][i]) % mod; for (int k = i; k <= n; ++k) dec(a[j][k], 1ll * a[i][k] * d % mod); } } return ret; } } a[2];
void dickdreamer() { std::cin >> n >> m >> mod; for (int i = 1; i <= (n + 1) * (m + 1); ++i) fa[i] = i; for (int i = 1; i <= n; ++i) { std::cin >> s[i]; s[i] = " " + s[i]; for (int j = 1; j <= m; ++j) { if (s[i][j] == '/') { if (!unionn(getid(i, j + 1), getid(i + 1, j))) return void(std::cout << "0\n"); } else if (s[i][j] == '\\') { if (!unionn(getid(i, j), getid(i + 1, j + 1))) return void(std::cout << "0\n"); } else { ++k; } } } std::vector<int> v[2]; for (int i = 1; i <= (n + 1) * (m + 1); ++i) { if (find(i) == i) { v[((i - 1) / (m + 1) + (i - 1) % (m + 1)) & 1].emplace_back(i); } } a[0].set(v[0].size()), a[1].set(v[1].size()); for (int i = 1; i <= n; ++i) { for (int j = 1; j <= m; ++j) { if (s[i][j] == '*') { int o = (i + j) & 1; if ((int)v[o].size() <= k + 1) a[o].add(getpos(v[o], find(getid(i, j))), getpos(v[o], find(getid(i + 1, j + 1)))); if ((int)v[o ^ 1].size() <= k + 1) a[o ^ 1].add(getpos(v[o ^ 1], find(getid(i + 1, j))), getpos(v[o ^ 1], find(getid(i, j + 1)))); } } } std::cout << add(a[0].getdet(), a[1].getdet()) << '\n'; }
int32_t main() { #ifdef ORZXKR freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout); #endif std::ios::sync_with_stdio(0), std::cin.tie(0), std::cout.tie(0); int T = 1; while (T--) dickdreamer(); return 0; }
|