vector vis(n, vector<int>(m)); vector<array<int, 2>> a(k + 1); for (auto& [x, y] : a) { cin >> x >> y; x--; y--; vis[x][y] = 1; }
bool ok = true; vector need(n, vector<vector<int>>(m)); vector<vector<array<int, 2>>> adj(k); for (int i = 0; i < k; i++) { auto [x0, y0] = a[i + 1]; auto [x1, y1] = a[i]; if (abs(x0 - x1) + abs(y0 - y1) != 2) { ok = false; break; } if (x0 == x1 || y0 == y1) { int x = (x0 + x1) / 2; int y = (y0 + y1) / 2; if (vis[x][y]) { ok = false; break; } need[x][y].push_back(i); adj[i].push_back({ x, y }); } else { if (vis[x0][y1] && vis[x1][y0]) { ok = false; break; } if (!vis[x0][y1]) { need[x0][y1].push_back(i); adj[i].push_back({ x0, y1 }); } if (!vis[x1][y0]) { need[x1][y0].push_back(i); adj[i].push_back({ x1, y0 }); } } } queue<int> Q; for (int i = 0; i < k; i++) { if (adj[i].size() == 1) { Q.push(i); } } while (!Q.empty()) { int u = Q.front(); Q.pop(); if (adj[u].size() != 1) { ok = false; break; } auto [x, y] = adj[u][0]; if (vis[x][y]) { ok = false; break; } vis[x][y] = 1; for (auto v : need[x][y]) { auto it = find(adj[v].begin(), adj[v].end(), array<int, 2>{x, y}); if (it == adj[v].end()) continue; adj[v].erase(it); if (adj[v].size() == 1) { Q.push(v); } } }
vector<vector<int>> dsu(n * m); vector<int> cnt(n * m); for (int i = 0; i < n * m; i++) { dsu[i].push_back(i); cnt[i] = 1; } auto uno = [&](int u, int v) { if (u = dsu[u][0], v = dsu[v][0]; u == v) { cnt[u]++; return; } if (dsu[u].size() < dsu[v].size()) swap(u, v); for (auto x : dsu[v]) { dsu[u].push_back(x); dsu[x] = { u }; } cnt[u] += cnt[v]; }; auto change = [&](array<int, 2> x) { return x[0] * m + x[1]; }; for (int i = 0; i < k; i++) { if (adj[i].size() == 2) { uno(change(adj[i][0]), change(adj[i][1])); } } ll res = 1; for (int i = 0; i < n * m; i++) { if (i == dsu[i][0]) { if (cnt[i] > dsu[i].size() + 1) { ok = false; } elseif (cnt[i] == dsu[i].size() + 1) { res *= 2; } elseif (cnt[i] == dsu[i].size()) { res *= cnt[i]; } res %= mod; } } if (!ok) { res = 0; } cout << res << endl; }
constexpr pair<ll, ll> exgcd(ll a, ll b){ // 满足 ax + by = gcd(a, b) 的一个解 x a %= b; if (a < 0) a += b; if (a == 0) return { b, 0 }; ll s = b, t = a; ll m0 = 0, m1 = 1; while (t) { ll u = s / t; s -= t * u; m0 -= m1 * u; swap(s, t); swap(m0, m1); } if (m0 < 0) m0 += b / s; return { s, m0 }; }
pair<ll, ll> exexgcd(ll a, ll b, ll c){ ll d = gcd(a, b); if (c % d) return { -1, -1 }; // 无解 a /= d, b /= d, c /= d; auto [s, x] = exgcd(a, b); ll y = (c - a * x) / b; x = ((x * c % b) + b * d) % b; y = (c - a * x) / b; return { x, y }; } // 同余方程 ax == c (mod b) 的最小正整数解 // 即解不定方程 ax + by = c // 调用 exexgcd(a,b,c);
while (t--) { int n, x, y, u, v; cin >> n >> x >> y >> u >> v;
int d = gcd(u, v); u /= d; v /= d;
int g1 = gcd(u, n); if (x % g1) { cout << -1 << endl; continue; } int n1 = n / g1; int x1 = x / g1; int u1 = u / g1; auto [a, _] = exexgcd(u1, n1, -x1);
int g2 = gcd(v, n); if (y % g2) { cout << -1 << endl; continue; } int n2 = n / g2; int y2 = y / g2; int v2 = v / g2; auto [b, _] = exexgcd(v2, n2, -y2);
int g = gcd(n1, n2); if ((a - b) % g) { cout << -1 << endl; continue; } auto [p, q] = exexgcd(n1, n2, b - a); q = -q; ll k = p * n1 + a;
x = x + k * u; y = y + k * v;
ll res = 0; res += x / n - 1; res += y / n - 1; res += (x + y) / (2 * n); res += abs(x - y) / (2 * n); cout << res << endl; }