QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#716836 | #9570. Binary Tree | ucup-team2179# | RE | 1ms | 3544kb | C++20 | 3.4kb | 2024-11-06 16:09:00 | 2024-11-06 16:09:04 |
Judging History
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 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 + 1 - sz[u];
};
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});
Query.pb({a[p][i], p, a[p][j], mxsz});
}
}
sort(Query.begin(),Query.end());
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;
for(int i=1;i<=n;i++){
int u,v;
cin>>u>>v;
if(u)a[i].pb(u),a[u].pb(i);
if(v)a[i].pb(v),a[v].pb(i);
node.insert(i);
}
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);
}
};
dfs(1, 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;
}
详细
Test #1:
score: 100
Accepted
time: 1ms
memory: 3544kb
input:
2 5 0 0 1 5 2 4 0 0 0 0 2 0 2 0 2 0 0 2
output:
? 1 3 ? 3 4 ! 3 ? 1 2 ! 2
result:
ok OK (2 test cases)
Test #2:
score: -100
Runtime Error
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 2 1 3 3 0 1 0 0 0 2 2 2 0 0 0 2 3 2 3 0 0 0 0 1 10 2 8 9 7 0 0 ...
output:
? 1 8 ? 3 8 ? 5 8 ! 5 ? 2 7 ? 7 8 ? 6 8 ! 6 ? 5 8 ? 4 2 ? 6 8 ! 8 ? 4 2 ? 1 5 ! 1 ? 5 6 ? 1 4 ! 4 ? 5 1 ? 4 5 ! 4 ? 3 5 ? 1 2 ! 5 ? 3 2 ! 2 ? 1 2 ! 2 ? 2 3 ! 1 ? 2 6 ? 1 9 ? 1 8 ! 1 ? 1 2 ! 2 ? 5 9 ? 4 8 ? 3 5 ! 3 ? 3 10 ? 6 8 ? 8 10 ! 10 ? 3 9 ? 1 7 ? 2 9 ! 9 ? 1 2 ! 2 ? 4 3 ? 1 7 ! 7 ? 6 2 ? 9 5 ?...