QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#742785 | #9570. Binary Tree | gates_orz | TL | 0ms | 0kb | C++20 | 4.5kb | 2024-11-13 17:18:58 | 2024-11-13 17:18:59 |
answer
#include <bits/stdc++.h>
using namespace std;
const int N=2e5+10;
const int M=N*2;
using LL=long long;
using PII=pair<int,int>;
int n,m;
deque<int>g[N];
int in[N],out[N],dfn;
int dep[N];
int lc[N],rc[N];
int fa[N][22];
int root;
int q1,q2;
int dot;
void add(int a,int b) {
g[a].push_back(b);
g[b].push_back(a);
}
void dfs(int u,int fat) {
dep[u]=dep[fat]+1;
if(dep[q1]<dep[u])q1=u;
fa[u][0]=fat;
in[u]=++dfn;
for(int i=1;i<=18;i++) {
fa[u][i]=fa[fa[u][i-1]][i-1];
}
for(auto v:g[u]) {
if(v==fat)continue;
dfs(v,u);
}
out[u]=++dfn;
}
int lca(int a,int b) {
if(dep[a]<dep[b])swap(a,b);
for(int k=18;k>=0;k--) {
if(dep[fa[a][k]]>=dep[b]) {
a=fa[a][k];
}
}
if(a==b)return a;
for(int k=18;k>=0;k--) {
if(fa[a][k]!=fa[b][k]) {
a=fa[a][k];
b=fa[b][k];
}
}
return fa[a][0];
}
bool isAncestor(int u,int fa) {
if(u==fa)return true;
return in[fa]<in[u]&&out[fa]>out[u];
}
int get_KthAncestor(int u,int k) {
int res=u;
for(int i=18;i>=0;i--) {
if(k>=(1<<i)) {
k-=(1<<i);
res=fa[res][i];
}
}
return res;
}
void get_leaf(int u) {
dot=u;
for(auto v:g[u]) {
if(dep[v]<dep[u])continue;
get_leaf(v);
}
}
void get_other_leaf(int u,int f) {
dot=f;
for(auto v:g[f]) {
if(dep[v]<dep[f])continue;
if(isAncestor(u,v))continue;
dot=v;
}
if(dot!=f)get_leaf(dot);
}
int Dis(int a,int b) {
int p=lca(a,b);
return dep[a]+dep[b]-dep[p]*2;
}
void solve() {
cin>>n;dfn=0;
q1=q2=0;
for(int i=1;i<=n;i++) {
g[i].clear();
in[i]=0,out[i]=0;
lc[i]=rc[i]=0;
}
vector<int>vis(n+1,0);
for(int i=1;i<=n;i++) {
int a,b;
cin>>a>>b;
if(a) {
add(i,a);
//add(a,i);
vis[a]=1;
}
if(b) {
add(i,b);
//add(b,i);
vis[b]=1;
}
}
for(int i=1;i<=n;i++) {
if(!vis[i]) {
root=i;
break;
}
}
dfs(root,0);
int now_root=root;
//cerr<<"root="<<root<<"\n";
while(true) {
//cerr<<"now_root="<<now_root<<"\n";
if(q1==now_root) {
cout<<"! "<<q1<<endl;
break;
}
int dis=Dis(q1,now_root);
int f=get_KthAncestor(q1,(dis+1)/2);
//cerr<<"q1="<<q1<<" f="<<f<<"\n";
get_other_leaf(q1,f);
q2=dot;
cout<<"? "<<q1<<" "<<q2<<endl;
dis=Dis(q1,q2);
int mid=get_KthAncestor(dep[q1]>dep[q2]?q1:q2,(Dis(q1,q2)-1)/2);
int t;
cin>>t;
if(t==0) {
//cerr<<"q1="<<q1<<" k="<<(dis+1)/2-1<<"\n";
now_root=get_KthAncestor(q1,(dis+1)/2-1);
}
else if(t==2) {
//mid=fa[mid][0];
if(dep[q1]>dep[q2])mid=fa[mid][0];
//cerr<<"mid="<<mid<<"\n";
vector<int>del;
for(auto tmp:g[mid]) {
if(isAncestor(q1,tmp))del.push_back(tmp);
}
sort(del.begin(),del.end(),[&](int a,int b) {
return dep[a]>dep[b];
});
if(g[mid].front()==del.front()) g[mid].pop_front();
else if(g[mid].back()==del.front()) g[mid].pop_back();
else {
int tt=g[mid].front();
g[mid].pop_front();
g[mid].pop_front();
g[mid].push_front(tt);
}
//cerr<<"del: "<<mid<<" "<<del.front()<<endl;
if(dep[q1]<=dep[q2])now_root=mid;
get_leaf(mid);
q1=dot;
//for(auto v:g[mid])cerr<<"v="<<v<<"\n";
//cerr<<"q1="<<q1<<"\n";
}
else if(t==1) {
/*cout<<"! "<<get_KthAncestor(dep[q1]>dep[q2]?q1:q2,Dis(q1,q2)/2)<<endl;
break;*/
if(dep[q1]>dep[q2])mid=fa[mid][0];
q1=mid;
}
}
}
/*
1
5
0 0
1 5
2 4
0 0
0 0
1
2
0 2
0 0
10
0 0
1 3
0 0
2 5
6 0
0 0
4 0
7 0
8 0
9 0
1
15
2 3
4 5
6 7
8 9
10 11
12 13
14 15
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0
*/
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
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
Time Limit Exceeded
input:
2 5 0 0 1 5 2 4 0 0 0 0 1 1
output:
? 1 5 ? 5 1 ? 1 5