QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#728457 | #9570. Binary Tree | ucup-team045# | WA | 22ms | 3560kb | C++20 | 8.3kb | 2024-11-09 15:13:39 | 2024-11-09 15:13:40 |
Judging History
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)