QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#728457#9570. Binary Treeucup-team045#WA 22ms3560kbC++208.3kb2024-11-09 15:13:392024-11-09 15:13:40

Judging History

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

  • [2024-11-09 15:13:40]
  • 评测
  • 测评结果:WA
  • 用时:22ms
  • 内存:3560kb
  • [2024-11-09 15:13:39]
  • 提交

answer

#include<iostream>
#include<cstring>
#include<vector>
#include<array>
#include<algorithm>
#include<numeric>
using namespace std;
using LL = long long;

// 1_based HLD
// struct Edge{
//     int to;
//     int w;
//     operator int() const { return to; }
// };

using Edge = int;
struct HLD{
    int n;
    vector<int> sz, top, dep, fa, in, out, seq;
    vector<vector<Edge> > g;
    int ts;

    HLD(const vector<vector<Edge> > &g, int root = 1) : n(int(g.size()) - 1), g(g)  {
        ts = 0;
        sz.resize(n + 1);
        top.resize(n + 1);
        dep.resize(n + 1);
        fa.resize(n + 1);
        in.resize(n + 1);
        out.resize(n + 1);
        seq.resize(n + 1);
        dep[root] = 1;
        top[root] = root;
        dfs_sz(root);
        dfs_hld(root);
    }

    void dfs_sz(int u){
        if (fa[u]){
            for(auto it = g[u].begin(); it != g[u].end(); it++){
                if (*it == fa[u]){
                    g[u].erase(it);
                    break;
                }
            }
        }
        sz[u] = 1;
        for(auto &j : g[u]){
            fa[j] = u;
            dep[j] = dep[u] + 1;
            dfs_sz(j);
            sz[u] += sz[j];
            if (sz[j] > sz[g[u][0]])
                swap(j, g[u][0]);
        }
    }

    void dfs_hld(int u){
        in[u] = ++ts;
        seq[in[u]] = u;
        for (auto j : g[u]){
            top[j] = (j == g[u][0] ? top[u] : j);
            dfs_hld(j);
        }
        out[u] = ts;
    }

    int lca(int u, int v){
        while (top[u] != top[v]){
            if (dep[top[u]] > dep[top[v]]){
                u = fa[top[u]];
            } 
            else{
                v = fa[top[v]];
            }
        }
        return dep[u] < dep[v] ? u : v;
    }

    int dist(int u, int v){
        return dep[u] + dep[v] - 2 * dep[lca(u, v)];
    }

    bool in_subtree(int u, int v){
        return in[v] <= in[u] && in[u] <= out[v];
    }
    
    int jump(int u, int k) {
        if (dep[u] < k){
            return -1;
        }
        int d = dep[u] - k;
        while (dep[top[u]] > d){
            u = fa[top[u]];
        }
        return seq[in[u] - dep[u] + d];
    }
    
    int rooted_lca(int a, int b, int c){
        return lca(a, b) ^ lca(b, c) ^ lca(c, a);
    }

    template<typename Q>
    void modify_path(int u, int v, const Q &q, bool edge = false){
        while(top[u] != top[v]){
            if (dep[top[u]] < dep[top[v]]) swap(u, v);
            q(in[top[u]], in[u]);
            u = fa[top[u]];        
        }
        if (dep[u] > dep[v]) swap(u, v);
        q(in[u] + edge, in[v]);
    }

    template<typename Q>
    void modify_subtree(int u, const Q &q){
        q(in[u], out[u]);
    }  

    template<typename T, typename Q>
    T query_path(int u, int v, const Q &q, bool edge = false){
        T ret = T();
        while(top[u] != top[v]){
            if (dep[top[u]] < dep[top[v]]) swap(u, v);
            ret = q(in[top[u]], in[u]) + ret;
            u = fa[top[u]];
        }
        if (dep[u] > dep[v]) swap(u, v);
        return q(in[u] + edge, in[v]) + ret;
    }

    template<typename T, typename Q>
    T query_subtree(int u, const Q &q){
        return q(in[u], out[u]);
    }

    template<typename T, typename Q, typename F>
    T query_path_noncommutative(int u, int v, const Q &q, const F &f, bool edge = false){
        T left = T(), right = T();
        while(top[u] != top[v]){
            if (dep[top[u]] < dep[top[v]]) swap(u, v), swap(left, right);
            left = q(in[top[u]], in[u]) + left;
            u = fa[top[u]];
        }
        if (dep[u] > dep[v]) swap(u, v), swap(left, right);
        return f(left, q(in[u] + edge, in[v]) + right);
    }
    
    pair<vector<int>, vector<pair<int, int> > > compress(vector<int> v){
        auto cmp = [&](int a, int b) { return in[a] < in[b]; };
        sort(v.begin(), v.end(), cmp);
        v.erase(unique(v.begin(), v.end()), v.end());
        const int k = (int)v.size();
        for(int i = 0; i + 1 < k; i++){
            v.push_back(lca(v[i], v[i + 1]));
        }
        sort(v.begin(), v.end(), cmp);
        v.erase(unique(v.begin(), v.end()), v.end());
        vector<pair<int, int> > edges;
        vector<int> stk;
        for(auto x : v){
            while(!stk.empty() && out[stk.back()] < in[x]){
                stk.pop_back();
            }
            if (!stk.empty()){
                edges.push_back({stk.back(), x});
            }
            stk.push_back(x);
        }
        return {v, edges};
    }

};

int main(){

#ifdef LOCAL
    freopen("data.in", "r", stdin);
    freopen("data.out", "w", stdout);
#endif

    cin.tie(0);
    cout.tie(0);
    ios::sync_with_stdio(0);

    int hidden = 1;

    int T;
    cin >> T;
    while(T--){
        int n;
        cin >> n;
        vector<int> pt(n);
        iota(pt.begin(), pt.end(), 1);
        vector<pair<int, int> > edge;
        vector<vector<int> > gg(n + 1);

        for(int i = 1; i <= n; i++){
            for(int j = 0; j < 2; j++){
                int x;
                cin >> x;
                if (x){
                    edge.push_back({i, x});
                    gg[x].push_back(i);
                    gg[i].push_back(x);
                }
            }
        }

        HLD hld(gg);

        auto ask = [&](int x, int y){
            cout << "? " << x << ' ' << y << endl;
        #ifdef LOCAL
            int d1 = hld.dist(x, hidden);
            int d2 = hld.dist(y, hidden);

            if (d1 < d2) return 0;
            if (d1 == d2) return 1;
            return 2;
        #endif
            int t;
            cin >> t;
            return t;
        };

        
        while(pt.size() > 1){
            if (pt.size() == 2){
                if (ask(pt[0], pt[1]) == 0){
                    pt = {pt[0]};
                }
                else{
                    pt = {pt[1]};
                }
                break;
            }
            
            vector<bool> v(n + 1);
            for(auto x : pt) v[x] = true;
            vector<vector<int> > g(n + 1);
            for(auto [x, y] : edge){
                if (v[x] and v[y]){
                    g[x].push_back(y);
                    g[y].push_back(x);
                }
            }

            vector<int> sz(n + 1), fa(n + 1);

            array<int, 3> best{};
            int mn = 0;

            auto dfs = [&](auto &&dfs, int u) -> void {
                sz[u] = 1;
                vector<int> sons;
                for(auto j : g[u]){
                    if (!v[j] or j == fa[u]) continue;
                    sons.push_back(j);
                    fa[j] = u;
                    dfs(dfs, j);
                    sz[u] += sz[j];
                }
                if (sons.size() == 2){
                    int sz1 = sz[sons[0]];
                    int sz2 = sz[sons[1]];
                    int sz3 = pt.size() - sz1 - sz2;
                    int t = min({sz1, sz2, sz3});
                    if (t > mn){
                        mn = t;
                        best = {sons[0], u, sons[1]};
                    }
                }
            };

            int root = 0;
            while(g[pt[root]].size() == 3) root += 1;
            root = pt[root];
            dfs(dfs, root);
            for(auto u : pt){
                if (fa[fa[u]] != 0){
                    int sz1 = sz[u];
                    int sz2 = sz[fa[u]] - sz[u];
                    int sz3 = pt.size() - sz1 - sz2;
                    int t = min({sz1, sz2, sz3});
                    if (t > mn){
                        mn = t;
                        best = {u, fa[u], fa[fa[u]]};
                    }
                }
            }
            int t = best[ask(best[0], best[2])];
            v[best[0]] = v[best[1]] = v[best[2]] = false;
            v[t] = true;

            pt.clear();

            auto dfs1 = [&](auto &&dfs1, int u, int fa) -> void {
                pt.push_back(u);
                for(auto j : g[u]){
                    if (!v[j] or j == fa) continue;
                    dfs1(dfs1, j, u);
                }
            };

            dfs1(dfs1, t, -1);
        }
        cout << "! " << pt[0] << endl;
    }

}

详细

Test #1:

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

input:

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

output:

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

result:

ok OK (2 test cases)

Test #2:

score: -100
Wrong Answer
time: 22ms
memory: 3560kb

input:

5555
8
2 0
8 6
0 0
3 0
0 0
7 0
0 0
5 4
0
2
0
8
0 0
1 4
2 0
0 0
7 8
0 0
3 0
6 0
2
0
1
8
5 8
0 0
1 7
0 0
0 0
4 2
0 0
6 0
2
1
0
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
1
1
0
5
3 0
5 1
0 0
0 0
4 0
2
0
5
5 0
0 0
0 0
3 0
2 4
2
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 ...

output:

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

result:

wrong answer Too many queries (test case 14)