QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#431507 | #6847. Hide-And-Seek Game | ucup-team3591# | AC ✓ | 195ms | 3836kb | C++20 | 3.2kb | 2024-06-05 17:35:35 | 2024-06-05 17:35:36 |
Judging History
answer
// Code by Heratino & Nelofus
#include <bits/stdc++.h>
using i64 = long long;
template<typename T>
inline void chkmin(T &a, const T &b) {if (a > b) a = b;}
constexpr int N = 3e3 + 10;
constexpr i64 inf = 1e18;
std::basic_string<int> G[N];
int dep[N];
int fa[15][N];
int n, m;
inline void add(int u, int v) {G[u].push_back(v);}
void exgcd(i64 a, i64 b, i64 &x, i64 &y, i64 &d) {
if (b == 0) {
d = a, x = 1, y = 0;
} else {
exgcd(b, a % b, y, x, d);
y -= a / b * x;
}
}
void dfs(int u) {
dep[u] = dep[fa[0][u]] + 1;
for (const int &v : G[u]) {
if (v == fa[0][u])
continue;
fa[0][v] = u;
dfs(v);
}
}
void clear() {
for (int i = 1; i <= n; i++) {
G[i].clear(), dep[i] = 0;
for (int j = 0; j < 15; j++)
fa[j][i] = 0;
}
}
inline int LCA(int u, int v) {
if (dep[u] < dep[v])
std::swap(u, v);
for (int k = 14; k >= 0; k--)
if (dep[fa[k][u]] >= dep[v])
u = fa[k][u];
if (u == v)
return u;
for (int k = 14; k >= 0; k--)
if (fa[k][u] != fa[k][v])
u = fa[k][u], v = fa[k][v];
return fa[0][u];
}
inline int llen(int u, int v) {
int lca = LCA(u, v);
return dep[u] + dep[v] - 2 * dep[lca];
}
void solve() {
std::cin >> n >> m;
clear();
for (int i = 1; i < n; i++) {
int u, v;
std::cin >> u >> v;
add(u, v), add(v, u);
}
dfs(1);
for (int k = 1; k < 15; k++)
for (int i = 1; i <= n; i++)
fa[k][i] = fa[k - 1][fa[k - 1][i]];
auto find = [&](int x, int y, std::set<int> &st) {
st.insert(y);
while (dep[x] > dep[y]) {
st.insert(x);
x = fa[0][x];
}
};
while (m--) {
i64 ans = -1;
i64 t = inf;
int sa, ta, sb, tb;
std::cin >> sa >> ta >> sb >> tb;
int alca = LCA(sa, ta), blca = LCA(sb, tb);
std::set<int> l1, l2;
find(sa, alca, l1);
find(ta, alca, l1);
find(sb, blca, l2);
find(tb, blca, l2);
int len1 = llen(sa, ta), len2 = llen(sb, tb);
auto upd = [&](int p, i64 ct) {
if (ct < t)
t = ct, ans = p;
};
auto sol = [&](int u) {
std::array<int, 2> p = {llen(u, sa), llen(u, ta)};
std::array<int, 2> q = {llen(u, sb), llen(u, tb)};
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
i64 x, y, pgcd;
i64 a = 2 * len1, b = p[i] + len1 * i;
i64 c = 2 * len2, d = q[j] + len2 * j;
// ax + b = cy + d
// ax - cy = d - b
if (d == b) {
// ax = by = lca(a, c)
upd(u, b);
continue;
}
exgcd(a, c, x, y, pgcd);
y = -y;
if ((d - b) % pgcd != 0)
continue;
// 求 x 的最小整数解
// 不能加 abs 。在负数里面处理是完全可行的。
i64 mul = (d - b) / pgcd;
x *= mul;
i64 step = c / pgcd;
x = (x % step + step) % step;
y = (d - b - a * x) / (-c);
// 显然圈数 >= 0
if (y >= 0)
upd(u, a * x + b);
}
}
};
for (const int &u : l1) {
if (l2.find(u) != l2.end()) {
sol(u);
}
}
std::cout << ans << '\n';
}
}
int main() {
#ifdef HeratinoNelofus
freopen("input.txt", "r", stdin);
#endif
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int T;
std::cin >> T;
while (T--) {
solve();
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 195ms
memory: 3836kb
input:
500 6 20 1 2 1 3 3 4 2 5 3 6 1 6 6 5 2 1 6 2 5 1 2 6 2 6 1 2 6 3 6 4 4 1 1 3 5 6 3 4 2 1 3 5 2 4 1 2 6 2 1 2 6 2 1 4 1 6 1 6 2 5 2 6 2 5 6 2 5 2 1 3 5 6 6 4 4 1 4 5 5 4 4 1 3 6 1 2 6 1 4 3 71 30 1 2 2 3 2 4 4 5 2 6 6 7 4 8 2 9 1 10 9 11 3 12 5 13 5 14 10 15 6 16 13 17 17 18 4 19 5 20 17 21 20 22 4 2...
output:
3 -1 -1 -1 6 3 -1 1 -1 1 3 1 2 -1 -1 3 4 1 -1 3 -1 11 2 -1 5 -1 17 -1 -1 5 -1 -1 -1 -1 2 -1 5 53 5 7 -1 -1 2 4 -1 -1 -1 -1 -1 -1 -1 5 -1 1 5 1 -1 -1 -1 -1 33 5 1 1 -1 1 -1 -1 -1 -1 7 -1 -1 9 5 3 -1 -1 -1 19 -1 -1 6 5 -1 -1 5 -1 -1 -1 -1 1 -1 7 -1 -1 1 -1 -1 -1 8 -1 13 -1 -1 -1 -1 4 5 -1 -1 5 -1 -1 8...
result:
ok 53199 lines