QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#281804#6847. Hide-And-Seek GameTaylorFlyAC ✓180ms4664kbC++203.4kb2023-12-10 20:23:592023-12-10 20:24:00

Judging History

你现在查看的是最新测评结果

  • [2023-12-10 20:24:00]
  • 评测
  • 测评结果:AC
  • 用时:180ms
  • 内存:4664kb
  • [2023-12-10 20:23:59]
  • 提交

answer

#include <bits/stdc++.h>
#define all(x) x.begin(), x.end()

using i64 = long long;

i64 exgcd(i64 a, i64 b, i64 &x, i64 &y) {
    if (!b) {
        x = 1, y = 0;
        return a;
    }
    i64 d = exgcd(b, a % b, x, y);
    i64 t = x;
    x = y;
    y = t - a / b * y;
    return d;
}

void solve() {
    int n, m;
    std::cin >> n >> m;
    std::vector<std::vector<int>> G(n);
    for (int i = 0; i < n - 1; i++) {
        int u, v;
        std::cin >> u >> v;
        u--, v--;
        G[u].push_back(v);
        G[v].push_back(u);
    }
    std::vector<int> dep(n);
    std::vector fa(n, std::vector<int>(30));
    auto dfs = [&](auto self, int u, int father) -> void {
        fa[u][0] = father;
        for (int i = 1; i <= 25; i++) {
            if (fa[u][i - 1] == -1) fa[u][i] = -1;
            else fa[u][i] = fa[fa[u][i - 1]][i - 1];
        }
        for (int v : G[u]) {
            if (v == father) continue;
            dep[v] = dep[u] + 1;
            self(self, v, u);
        }
    };
    dfs(dfs, 0, -1);

    auto lca = [&](int x, int y) {
        if (dep[x] < dep[y]) {
            std::swap(x, y);
        }
        for (int i = 25; i >= 0; i--) {
            if (fa[x][i] != -1 && dep[fa[x][i]] >= dep[y]) {
                x = fa[x][i];
            }
        }
        if (x == y) return x;
        for (int i = 25; i >= 0; i--) {
            if (fa[x][i] != fa[y][i]) {
                x = fa[x][i];
                y = fa[y][i];
            }
        }
        return fa[x][0];
    };
    auto get_path = [&](int s, int t) {
        int top = lca(s, t);
        std::vector<int> a;
        while (s != top) {
            a.push_back(s);
            s = fa[s][0];
        }
        a.push_back(top);
        std::vector<int> b;
        while (t != top) {
            b.push_back(t);
            t = fa[t][0];
        }
        while (b.size()) a.push_back(b.back()), b.pop_back();
        return a;
    };

    while (m--) {
        int s1, t1, s2, t2;
        std::cin >> s1 >> t1 >> s2 >> t2;
        s1--, t1--, s2--, t2--;
        auto a = get_path(s1, t1);
        int sz = (int)a.size();
        for (int i = sz - 2; i >= 1; i--) {
            a.push_back(a[i]);
        }
        auto b = get_path(s2, t2);
        sz = b.size();
        for (int i = sz - 2; i >= 1; i--) {
            b.push_back(b[i]);
        }

        int g = std::gcd(a.size(), b.size());
        if (a.size() < b.size()) std::swap(a, b);
        int mn = 2e9, ans = -1;

        std::vector<std::vector<int>> p(n);
        for (int i = 0; i < a.size(); i++) {
            p[a[i]].push_back(i);
        }

        for (int j = 0; j < b.size(); j++) {
            for (int i: p[b[j]]) {
                int N = a.size(), M = -b.size(), C = j - i;
                i64 x, y;
                int D = exgcd(N, M, x, y);
                if (C % D) continue;
                x = x * C / D;
                int t = abs(M / D);
                x = (x % t + t) % t;
                if (x * N + i < mn) {
                    mn = x * N + i;
                    ans = b[j] + 1;
                }
            }
        }
        std::cout << ans << "\n";
    }
}

int main() {
    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: 180ms
memory: 4664kb

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