QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#716878 | #9570. Binary Tree | ucup-team2179# | RE | 0ms | 0kb | C++20 | 3.8kb | 2024-11-06 16:15:09 | 2024-11-06 16:15:16 |
answer
#include<bits/stdc++.h>
#define int long long
#define pii pair<int, int>
#define ll long long
#define pb push_back
using namespace std;
int lim;
int query(int a,int c,int b){
cout << "? "<<a << " " << b << endl;
int res;
cin>>res;
lim--;
if(res==0)return a;
if(res==1)return c;
if(res==2)return b;
}
const int N = 2e5 + 5;
int dep[N];
int par[N][22];
int C = 19;
int lca(int x,int y){
if(dep[y]>dep[x])swap(x,y);
for (int i = C - 1;i>=0;i--){
if(dep[par[x][i]]>=dep[y])
x = par[x][i];
}
if(x==y)return y;
for (int i = C - 1;i>=0;i--){
if(par[x][i]!=par[y][i]){
x=par[x][i];
y=par[y][i];
}
}
return par[x][0];
}
int dis(int u,int v){
return dep[u] + dep[v] - 2 * dep[lca(u, v)];
}
int n;
struct que{
int a,c,b;
int mxsz;
bool operator<(const que&B)const {
return mxsz < B.mxsz;
}
void print(){
cout << a << " " << c << " " << b << " " << mxsz << endl;
}
};
void work(vector<vector<int>>&a,set<int>node){
if(node.size()==1){
cout << "! "<<*node.begin() << endl;
return;
}
if(node.size()==2){
int ans = query(*node.begin(), *node.begin(), *node.rbegin());
cout << "! " << ans << endl;
return;
}
int cnt = node.size();
vector<int>sz(n+1);
int root = *node.begin();
for(auto p:node)if(dep[p]<dep[root])
root = p;
function<void(int, int)> dfs = [&](int u, int f) {
sz[u]++;
for(auto p:a[u]){
if(p==f)continue;
if(!node.count(p))continue;
dfs(p,u);
sz[u] += sz[p];
}
};
auto fsz = [&](int u, int f) {
if(dep[f]<dep[u])return sz[u];
return cnt - sz[f];
};
dfs(root, 0);
vector<que> Query;
for(auto p:node){
for (int i = 0; i < (int)a[p].size();i++)
for (int j = i + 1; j < (int)a[p].size();j++){
int mxsz=0;
int sz1 = fsz(a[p][i], p);
int sz2 = fsz(a[p][j], p);
mxsz = max({sz1, sz2, cnt - sz1 - sz2});
que now = {a[p][i], p, a[p][j], mxsz};
Query.pb(now);
// now.print();
}
}
sort(Query.begin(),Query.end());
// cout << Query[0].mxsz << endl;
// cout << Query[0].a<<" "<<Query[0].c<<" "<<Query[0].b << endl;
assert(Query[0].mxsz<= cnt/2);
set<int> s;
s.insert(Query[0].a);
s.insert(Query[0].b);
s.insert(Query[0].c);
int newtr = query(Query[0].a,Query[0].c,Query[0].b);
s.erase(newtr);
int other1 = *s.begin();
int other2 = *s.rbegin();
set<int> newnode;
for(auto p:node){
if(dis(p,newtr)<dis(p,other1)&&dis(p,newtr)<dis(p,other2))
newnode.insert(p);
}
work(a, newnode);
}
void solve() {
cin >> n;
lim = __lg(n);
vector<vector<int>> a(n + 1);
set<int> node;
set<int> last;
for(int i=1;i<=n;i++)
last.insert(i);
for(int i=1;i<=n;i++){
int u,v;
cin>>u>>v;
last.erase(u);
last.erase(v);
if(u)a[i].pb(u),a[u].pb(i);
if(v)a[i].pb(v),a[v].pb(i);
node.insert(i);
}
int root = *last.begin();
function<void(int, int)> dfs = [&](int u, int f) {
dep[u]=dep[f]+1;
par[u][0] = f;
for (int i = 1; i < C;i++)
par[u][i] = par[par[u][i - 1]][i - 1];
for(auto p:a[u]){
if(p==f)continue;
dfs(p, u);
}
};
cout << root << endl;
dfs(root, 0);
work(a,node);
}
signed main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--)
solve();
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Runtime Error
input:
2 5 0 0 1 5 2 4 0 0 0 0
output:
3 ? 1 3