QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#728563#9570. Binary Treeucup-team133#WA 2ms3612kbC++234.6kb2024-11-09 15:27:322024-11-09 15:27:36

Judging History

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

  • [2024-11-09 15:27:36]
  • 评测
  • 测评结果:WA
  • 用时:2ms
  • 内存:3612kb
  • [2024-11-09 15:27:32]
  • 提交

answer

#include <bits/stdc++.h>
#ifdef LOCAL
#include <debug.hpp>
#else
#define debug(...) void(0)
#endif

template <class T> std::istream& operator>>(std::istream& is, std::vector<T>& v) {
    for (auto& e : v) {
        is >> e;
    }
    return is;
}

template <class T> std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) {
    for (std::string_view sep = ""; const auto& e : v) {
        os << std::exchange(sep, " ") << e;
    }
    return os;
}

template <class T, class U = T> bool chmin(T& x, U&& y) {
    return y < x and (x = std::forward<U>(y), true);
}

template <class T, class U = T> bool chmax(T& x, U&& y) {
    return x < y and (x = std::forward<U>(y), true);
}

template <class T> void mkuni(std::vector<T>& v) {
    std::ranges::sort(v);
    auto result = std::ranges::unique(v);
    v.erase(result.begin(), result.end());
}

template <class T> int lwb(const std::vector<T>& v, const T& x) {
    return std::distance(v.begin(), std::ranges::lower_bound(v, x));
}

struct CentroidDecomposition {
    std::vector<std::vector<int>> G;

    CentroidDecomposition(int n) : G(n), n(n), sub(n), is_centroid(n) {}

    void add_edge(int u, int v) {
        assert(0 <= u && u < n);
        assert(0 <= v && v < n);
        G[u].emplace_back(v);
        G[v].emplace_back(u);
    }

    std::vector<int> build(int x = 0) {
        centroids.clear();
        fill(is_centroid.begin(), is_centroid.end(), false);
        centroid_decomposition(x);
        return centroids;
    }

  private:
    int n;
    std::vector<int> sub, centroids;
    std::vector<bool> is_centroid;

    int dfs_sz(int v, int p) {
        sub[v] = 1;
        for (int& u : G[v]) {
            if (u == p || is_centroid[u]) continue;
            sub[v] += dfs_sz(u, v);
        }
        return sub[v];
    }

    int dfs_search_centroid(int v, int p, int mid) {
        for (int& u : G[v]) {
            if (u == p || is_centroid[u]) continue;
            if (sub[u] > mid) return dfs_search_centroid(u, v, mid);
        }
        return v;
    }

    void centroid_decomposition(int r) {
        int centroid = dfs_search_centroid(r, -1, dfs_sz(r, -1) / 2);
        centroids.emplace_back(centroid);
        is_centroid[centroid] = true;
        for (int& ch : G[centroid]) {
            if (is_centroid[ch]) continue;
            centroid_decomposition(ch);
        }
    }
};

using namespace std;

using ll = long long;

int n;

int query(int u, int v) {
    assert(0 <= u and u < n);
    assert(0 <= v and v < n);
    cout << "? " << u + 1 << " " << v + 1 << endl;
    int res;
    cin >> res;
    return res;
};

void answer(int s) {
    assert(0 <= s and s < n);
    cout << "! " << s + 1 << endl;
}

void solve() {
    cin >> n;
    vector<int> x(n), y(n);
    for (int i = 0; i < n; i++) {
        cin >> x[i] >> y[i];
        x[i]--, y[i]--;
    }

    vector<vector<int>> G(n);
    for (int i = 0; i < n; i++) {
        if (x[i] != -1) {
            G[i].emplace_back(x[i]);
            G[x[i]].emplace_back(i);
        }
        if (y[i] != -1) {
            G[i].emplace_back(y[i]);
            G[y[i]].emplace_back(i);
        }
    }
    vector<int> sub(n), used(n, false);
    auto dfs_sz = [&](auto self, int v, int p) -> int {
        sub[v] = 1;
        for (int& u : G[v]) {
            if (u == p or used[u]) continue;
            sub[v] += self(self, u, v);
        }
        return sub[v];
    };
    auto dfs_search = [&](auto self, int v, int p, int mid) -> int {
        for (int& u : G[v]) {
            if (u == p or used[u]) continue;
            if (sub[u] > mid) return self(self, u, v, mid);
        }
        return v;
    };

    for (int r = 0;;) {
        r = dfs_search(dfs_search, r, -1, dfs_sz(dfs_sz, r, -1) / 2);
        vector<int> cand;
        for (int& adj : G[r]) {
            if (not used[adj]) {
                cand.emplace_back(adj);
            }
        }
        int len = cand.size();
        debug(r, cand);
        if (len == 0) {
            answer(r);
            return;
        }
        if (len == 1) {
            int u = r, v = cand[0];
            int res = query(u, v);
            assert(res != 1);
            if (res == 2) swap(u, v);
            used[v] = true;
            r = u;
        } else {
            int u = cand[0], v = cand[1];
            int res = query(u, v);
            if (res == 1) {
                used[u] = used[v] = true;
            } else {
                if (res == 2) swap(u, v);
                used[r] = true;
                r = u;
            }
        }
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);

    int T;
    cin >> T;
    for (; T--;) solve();
    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 1ms
memory: 3612kb

input:

2
5
0 0
1 5
2 4
0 0
0 0
1
1
2
0 2
0 0
2

output:

? 1 5
? 2 4
! 3
? 1 2
! 2

result:

ok OK (2 test cases)

Test #2:

score: -100
Wrong Answer
time: 2ms
memory: 3556kb

input:

5555
8
2 0
8 6
0 0
3 0
0 0
7 0
0 0
5 4
2
2
0
8
0 0
1 4
2 0
0 0
7 8
0 0
3 0
6 0
2
2
0
8
5 8
0 0
1 7
0 0
0 0
4 2
0 0
6 0
2
1
2
5
4 5
3 1
0 0
0 0
0 0
1
0
8
0 0
0 0
5 6
0 0
1 4
2 0
3 8
0 0
0
2
5
3 0
5 1
0 0
0 0
4 0
0
0
5
5 0
0 0
0 0
3 0
2 4
1
2
3
3 0
1 0
0 0
2
2
2 0
0 0
2
3
2 3
0 0
0 0
2
10
2 8
9 7
0 0
...

output:

? 1 8
? 5 4
? 4 3
! 4
? 2 7
? 7 8
? 8 6
! 8
? 5 8
? 4 2
? 6 8
! 8
? 4 5
? 3 1
! 3
? 5 6
? 1 4
! 4
? 5 1
? 5 4
! 5
? 1 2
? 3 5
! 5
? 3 2
! 2
? 1 2
! 2
? 2 3
! 3
? 1 9
? 2 6
? 4 3
! 4
? 1 2
! 1
? 5 9
? 2 1
? 2 6
! 2
? 3 10
? 6 2
? 4 10
! 10
? 3 4
? 1 7
? 8 2
! 2
? 1 2
! 2
? 4 3
? 1 7
! 7
? 4 9
? 8 4
?...

result:

wrong answer Too many queries (test case 90)